No public description

PiperOrigin-RevId: 903835803
diff --git a/rust/e2e_tests/testdata/fuzz_tests.rs b/rust/e2e_tests/testdata/fuzz_tests.rs
index 9b827a9..d4f8431 100644
--- a/rust/e2e_tests/testdata/fuzz_tests.rs
+++ b/rust/e2e_tests/testdata/fuzz_tests.rs
@@ -32,14 +32,14 @@
     type UserValue<'user> = Vec<u8>;
     type CorpusValue = Vec<u8>;
 
-    fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+    fn init(&mut self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
         let mut val = vec![0u8; rng.random_range(0..100)];
         rng.fill(&mut val[..]);
         Ok(val)
     }
 
     fn mutate(
-        &self,
+        &mut self,
         val: &mut Self::CorpusValue,
         rng: &mut dyn rand::Rng,
         only_shrink: bool,
@@ -78,6 +78,10 @@
     ) -> anyhow::Result<Self::UserValue<'a>> {
         Ok(val.clone())
     }
+
+    fn from_value(&self, value: Self::UserValue<'_>) -> anyhow::Result<Self::CorpusValue> {
+        Ok(value)
+    }
 }
 
 #[fuzztest(_a = Arbitrary::<bool>::default())]
@@ -160,12 +164,12 @@
     type UserValue<'user> = u32;
     type CorpusValue = u32;
 
-    fn init(&self, _rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+    fn init(&mut self, _rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
         Ok(0)
     }
 
     fn mutate(
-        &self,
+        &mut self,
         _val: &mut Self::CorpusValue,
         _rng: &mut dyn rand::Rng,
         _only_shrink: bool,
@@ -179,6 +183,10 @@
     ) -> anyhow::Result<Self::UserValue<'a>> {
         Ok(*val)
     }
+
+    fn from_value(&self, value: Self::UserValue<'_>) -> anyhow::Result<Self::CorpusValue> {
+        Ok(value)
+    }
 }
 
 #[fuzztest(a = FallibleDomain::new())]
diff --git a/rust/fuzztest_macro/src/helpers/fuzztest_domain.rs b/rust/fuzztest_macro/src/helpers/fuzztest_domain.rs
index 6cb6b58..3cb112a 100644
--- a/rust/fuzztest_macro/src/helpers/fuzztest_domain.rs
+++ b/rust/fuzztest_macro/src/helpers/fuzztest_domain.rs
@@ -77,14 +77,14 @@
         type UserValue<#user_value_lifetime_generic> = #domain_struct_name <#(#user_value_domain_generics),*>;
         type CorpusValue = #domain_struct_name <#(#corpus_domain_generics),*>;
 
-        fn init(&self, rng: &mut dyn ::fuzztest::reexports::rand::Rng) -> ::fuzztest::reexports::anyhow::Result<Self::CorpusValue> {
+        fn init(&mut self, rng: &mut dyn ::fuzztest::reexports::rand::Rng) -> ::fuzztest::reexports::anyhow::Result<Self::CorpusValue> {
           Ok(#domain_struct_name {
             #(#field_names: self.#field_names.init(rng)?),*
           })
         }
 
         fn mutate(
-            &self,
+            &mut self,
             val: &mut Self::CorpusValue,
             rng: &mut dyn ::fuzztest::reexports::rand::Rng,
             only_shrink: bool,
@@ -98,6 +98,17 @@
             #(#field_names: self.#field_names.get_user_value(&corpus_value.#field_names)?),*
           })
         }
+
+        fn from_value(&self, value: Self::UserValue<'_>) -> ::fuzztest::reexports::anyhow::Result<Self::CorpusValue> {
+          Ok(#domain_struct_name {
+            #(#field_names: self.#field_names.from_value(value.#field_names)?),*
+          })
+        }
+
+        fn validate_corpus_value(&self, corpus_value: &Self::CorpusValue) -> ::fuzztest::reexports::anyhow::Result<()> {
+          #( self.#field_names.validate_corpus_value(&corpus_value.#field_names)?; )*
+          Ok(())
+        }
       }
     };
     (domain_definition_tokens, field_names)
@@ -144,7 +155,7 @@
               type UserValue<'user> = __FuzzTestTestFuzzStateWrapper<T0::UserValue<'user>, T1::UserValue<'user> >;
               type CorpusValue = __FuzzTestTestFuzzStateWrapper<T0::CorpusValue, T1::CorpusValue>;
 
-              fn init(&self, rng: &mut dyn ::fuzztest::reexports::rand::Rng) -> ::fuzztest::reexports::anyhow::Result<Self::CorpusValue> {
+              fn init(&mut self, rng: &mut dyn ::fuzztest::reexports::rand::Rng) -> ::fuzztest::reexports::anyhow::Result<Self::CorpusValue> {
                 Ok(__FuzzTestTestFuzzStateWrapper {
                   a: self.a.init(rng)?,
                   b: self.b.init(rng)?
@@ -152,7 +163,7 @@
               }
 
               fn mutate(
-                  &self,
+                  &mut self,
                   val: &mut Self::CorpusValue,
                   rng: &mut dyn ::fuzztest::reexports::rand::Rng,
                   only_shrink: bool,
@@ -168,6 +179,19 @@
                   b: self.b.get_user_value(&corpus_value.b)?
                 })
               }
+
+              fn from_value(&self, value: Self::UserValue<'_>) -> ::fuzztest::reexports::anyhow::Result<Self::CorpusValue> {
+                Ok(__FuzzTestTestFuzzStateWrapper {
+                  a: self.a.from_value(value.a)?,
+                  b: self.b.from_value(value.b)?
+                })
+              }
+
+              fn validate_corpus_value(&self, corpus_value: &Self::CorpusValue) -> ::fuzztest::reexports::anyhow::Result<()> {
+                self.a.validate_corpus_value(&corpus_value.a)?;
+                self.b.validate_corpus_value(&corpus_value.b)?;
+                Ok(())
+              }
             }
           }
           .to_string())
diff --git a/rust/fuzztest_macro/src/helpers/test_registration.rs b/rust/fuzztest_macro/src/helpers/test_registration.rs
index 3806469..e843b4f 100644
--- a/rust/fuzztest_macro/src/helpers/test_registration.rs
+++ b/rust/fuzztest_macro/src/helpers/test_registration.rs
@@ -44,7 +44,8 @@
 }
 
 /// A context struct holding the pre-computed information and token streams required
-/// to generate the fuzz test registration, struct definitions, and integration with the test framework.
+/// to generate the fuzz test registration, struct definitions, and integration with the test
+/// framework.
 ///
 /// This context is created once per property function.
 pub struct FuzzTestRegistrationCtx<'a> {
@@ -60,7 +61,8 @@
 }
 
 impl<'a> FuzzTestRegistrationCtx<'a> {
-    /// Creates a new registration context from a property function signature and its domain constructors.
+    /// Creates a new registration context from a property function signature and its domain
+    /// constructors.
     ///
     /// This method analyzes the inputs, derives necessary identifiers and lifetime generics, and
     /// pre-computes the tokenstream for the fuzz test struct instance.
@@ -109,9 +111,11 @@
 
         let fuzz_test_struct_instance_tokens = quote!(
           #fuzz_test_struct_name {
-              domain: #domain_struct_name {
+              domain: std::sync::Arc::new(std::sync::Mutex::new(
+                #domain_struct_name {
                   #(#fuzz_test_domain_field_names: #domain_ctors),*
-              },
+                }
+              )),
               test_fn: #prop_fn_ident
           }
         );
@@ -212,7 +216,7 @@
         {
             where_clauses.predicates.push(
           parse_quote! {
-            for <#user_value_lifetime_generic> #domain_gen: #crate_name::domains::Domain<UserValue<#user_value_lifetime_generic> = #ty >
+            for <#user_value_lifetime_generic> #domain_gen: #crate_name::domains::Domain<UserValue<#user_value_lifetime_generic> = #ty > + 'static
         });
             where_clauses.predicates.push(parse_quote! { #corpus_gen: 'static });
         }
@@ -227,7 +231,7 @@
           #fuzz_test_domain_definition
 
           struct #fuzz_test_struct_name #generics {
-            domain: #domain_struct_name #generics,
+            domain: std::sync::Arc<std::sync::Mutex<#domain_struct_name #generics>>,
             test_fn: #test_fn_type
           }
 
@@ -248,7 +252,10 @@
                                 .downcast_ref::<#domain_struct_name<#(#corpus_generics),*>>()
                                 .expect("Attempt to recover user value before testing failed.");
 
-                  let user_value = self.domain.get_user_value(wrapper).expect("Failed to get user value from corpus value");
+                  let user_value = self.domain.lock()
+                  .expect("Failed to acquire domain lock")
+                  .get_user_value(wrapper)
+                  .expect("Failed to get user value from corpus value");
 
                   let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| (self.test_fn)(#(user_value.#fuzz_test_domain_field_names),* ) ));
 
@@ -257,8 +264,8 @@
               fn print_finding_report(&self) {
                   todo!("Not implemented!")
               }
-              fn domains(&self) -> &dyn #crate_name::domains::GenericDomain {
-                &self.domain
+              fn domains(&self) -> std::sync::Arc<std::sync::Mutex<dyn #crate_name::domains::GenericDomain>> {
+                std::sync::Arc::clone(&self.domain) as std::sync::Arc<std::sync::Mutex<dyn #crate_name::domains::GenericDomain>>
               }
           }
 
@@ -299,14 +306,14 @@
         expect_that!(
           fuzztest_object_tokenstream.to_string(), ends_with( quote! {
               struct __FuzzTestTestFuzz<T0, T1> {
-                domain: __FuzzTestTestFuzzStateWrapper<T0, T1>,
+                domain: std::sync::Arc<std::sync::Mutex<__FuzzTestTestFuzzStateWrapper<T0, T1> >>,
                 test_fn: fn(i32, std::string::String)
               }
 
               impl<T0, T1> ::fuzztest::internal::FuzzTest for __FuzzTestTestFuzz<T0, T1>
-              where for <'user> T0: ::fuzztest::domains::Domain<UserValue<'user> = i32>,
+              where for <'user> T0: ::fuzztest::domains::Domain<UserValue<'user> = i32> + 'static,
                     T0::CorpusValue: 'static,
-                    for <'user> T1: ::fuzztest::domains::Domain<UserValue<'user> = std::string::String>,
+                    for <'user> T1: ::fuzztest::domains::Domain<UserValue<'user> = std::string::String> + 'static,
                     T1::CorpusValue: 'static {
                   fn name(&self) -> &'static str {
                     "test_fuzz"
@@ -324,7 +331,10 @@
                             .downcast_ref::<__FuzzTestTestFuzzStateWrapper<T0::CorpusValue, T1::CorpusValue>>()
                             .expect("Attempt to recover user value before testing failed.");
 
-                    let user_value = self.domain.get_user_value(wrapper).expect("Failed to get user value from corpus value");
+                    let user_value = self.domain.lock()
+                        .expect("Failed to acquire domain lock")
+                        .get_user_value(wrapper)
+                        .expect("Failed to get user value from corpus value");
                     // Safety: Data is not reused after the test.
                     let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| (self.test_fn)(user_value.a, user_value.b) ));
 
@@ -333,17 +343,19 @@
                   fn print_finding_report(&self) {
                     todo!("Not implemented!")
                   }
-                  fn domains(&self) -> &dyn ::fuzztest::domains::GenericDomain {
-                    &self.domain
+                  fn domains(&self) -> std::sync::Arc<std::sync::Mutex<dyn ::fuzztest::domains::GenericDomain>> {
+                    std::sync::Arc::clone(&self.domain) as std::sync::Arc<std::sync::Mutex<dyn ::fuzztest::domains::GenericDomain>>
                   }
               }
 
               fn __FuzzTestTestFuzz_factory() -> ::fuzztest::internal::BoxedFuzzTest {
                 ::std::boxed::Box::new(__FuzzTestTestFuzz {
-                  domain: __FuzzTestTestFuzzStateWrapper {
-                    a: ::fuzztest::domains::arbitrary::Arbitrary::<i32>::default(),
-                    b: ::fuzztest::domains::arbitrary::Arbitrary::<String>::default()
-                  },
+                  domain: std::sync::Arc::new(std::sync::Mutex::new(
+                    __FuzzTestTestFuzzStateWrapper {
+                      a: ::fuzztest::domains::arbitrary::Arbitrary::<i32>::default(),
+                      b: ::fuzztest::domains::arbitrary::Arbitrary::<String>::default()
+                    }
+                  )),
                   test_fn: __property_fn__test_fuzz
                 })
               }
diff --git a/rust/src/domains.rs b/rust/src/domains.rs
index a873c59..0228aa5 100644
--- a/rust/src/domains.rs
+++ b/rust/src/domains.rs
@@ -123,14 +123,14 @@
     type CorpusValue: Serialize + DeserializeOwned + Clone;
 
     /// Initializes a new value drawn from the domain.
-    fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue>;
+    fn init(&mut self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue>;
 
     /// Mutates the value in `val` to a new value drawn from the domain.
     ///
     /// If `only_shrink` is `true`, then the mutation must not increase the size of the corpus
     /// value. Otherwise, the mutation can both shrink and grow the corpus value.
     fn mutate(
-        &self,
+        &mut self,
         val: &mut Self::CorpusValue,
         rng: &mut dyn rand::Rng,
         only_shrink: bool,
@@ -158,8 +158,130 @@
     fn serialize_corpus(&self, corpus_value: &Self::CorpusValue) -> anyhow::Result<Vec<u8>> {
         postcard::to_stdvec(corpus_value).context("Failed to serialize corpus value to bytes")
     }
+
+    /// Converts a user value to a corpus value.
+    #[allow(clippy::wrong_self_convention)]
+    fn from_value(&self, value: Self::UserValue<'_>) -> anyhow::Result<Self::CorpusValue>;
+
+    /// Validates that a corpus value satisfies the domain's constraints.
+    fn validate_corpus_value(&self, _corpus_value: &Self::CorpusValue) -> anyhow::Result<()> {
+        Ok(())
+    }
 }
 
+mod seeds {
+    use super::Domain;
+
+    use rand::RngExt;
+
+    use std::fmt;
+    use std::sync::Arc;
+
+    /// Helper struct that stores seeds and optional lazy seed provider for a domain.
+    #[derive(Clone)]
+    pub struct DomainSeeds<C> {
+        seeds: Vec<C>,
+        seed_provider: Option<Arc<Box<dyn Fn() -> Vec<C> + Send + Sync>>>,
+    }
+
+    impl<C> Default for DomainSeeds<C> {
+        fn default() -> Self {
+            Self { seeds: Vec::new(), seed_provider: None }
+        }
+    }
+
+    impl<C: fmt::Debug> fmt::Debug for DomainSeeds<C> {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            f.debug_struct("DomainSeeds")
+                .field("seeds", &self.seeds)
+                .field("has_seed_provider", &self.seed_provider.is_some())
+                .finish()
+        }
+    }
+
+    impl<C> DomainSeeds<C> {
+        pub fn new() -> Self {
+            Self::default()
+        }
+    }
+
+    /// Helper methods for the `DomainSeeds` struct. Those methods are private to the domain module
+    /// as they are not intended to be used by the user.
+    /// Internals of the `DomainSeeds` should only be accessed through the SeedableDomain trait.
+    impl<C: Clone> DomainSeeds<C> {
+        fn extend_seeds(&mut self, seeds: impl IntoIterator<Item = C>) {
+            self.seeds.extend(seeds);
+        }
+
+        fn set_provider<F>(&mut self, provider: F)
+        where
+            F: Fn() -> Vec<C> + Send + Sync + 'static,
+        {
+            self.seed_provider = Some(Arc::new(Box::new(provider)));
+        }
+
+        /// Returns a random seed with 50% probability. Does not call the seed provider as seeds
+        /// must be validated by the domain before being added to the domain seeds.
+        fn sample(&self, rng: &mut dyn rand::Rng) -> Option<C> {
+            if self.seeds.is_empty() || !rng.random_bool(0.5) {
+                None
+            } else {
+                let idx = rng.random_range(0..self.seeds.len());
+                Some(self.seeds[idx].clone())
+            }
+        }
+    }
+
+    pub trait SeedableDomain: Domain + Sized {
+        /// Mutable accessor to the domain's seed storage.
+        fn seeds_mut(&mut self) -> &mut DomainSeeds<Self::CorpusValue>;
+
+        /// Evaluates & validates the lazy seed provider (if any) once, then samples with 50%
+        /// probability.
+        fn sample_seed(
+            &mut self,
+            rng: &mut dyn rand::Rng,
+        ) -> anyhow::Result<Option<Self::CorpusValue>> {
+            if let Some(provider) = self.seeds_mut().seed_provider.take() {
+                let seeds = provider()
+                    .into_iter()
+                    .map(|s| self.validate_corpus_value(&s).map(|_| s))
+                    .collect::<anyhow::Result<Vec<Self::CorpusValue>>>()?;
+                self.seeds_mut().extend_seeds(seeds);
+            }
+            Ok(self.seeds_mut().sample(rng))
+        }
+
+        /// Adds pre-defined seeds. Panics if any seed is invalid for this domain.
+        fn with_seeds(
+            mut self,
+            seeds: impl IntoIterator<Item = impl Into<Self::CorpusValue>>,
+        ) -> Self {
+            for seed in seeds {
+                let corpus_val = seed.into();
+                if let Err(e) = self.validate_corpus_value(&corpus_val) {
+                    panic!("Invalid seed value for domain: {e:?}");
+                }
+                self.seeds_mut().extend_seeds([corpus_val]);
+            }
+            self
+        }
+
+        /// Adds a lazy seed provider evaluated on first sampling.
+        fn with_seed_provider<F, I, S>(mut self, seed_provider: F) -> Self
+        where
+            F: Fn() -> I + Send + Sync + 'static,
+            I: IntoIterator<Item = S>,
+            Self::CorpusValue: From<S>,
+        {
+            self.seeds_mut().set_provider(move || {
+                seed_provider().into_iter().map(Self::CorpusValue::from).collect()
+            });
+            self
+        }
+    }
+} // mod seeds
+
 /// A type-erased interface for Domain types.
 ///
 /// This trait is used to expose a common interface for Domain types to the fuzzing engine through
@@ -170,14 +292,14 @@
     /// Initializes a new value drawn from the domain.
     ///
     /// See `Domain::init` for more details.
-    fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<GenericCorpusValue>;
+    fn init(&mut self, rng: &mut dyn rand::Rng) -> anyhow::Result<GenericCorpusValue>;
 
     /// Mutates the value in `val` to a new value drawn from the domain.
     ///
     /// See `Domain::mutate` for more details.
     fn mutate(
-        &self,
-        val: &mut GenericCorpusValue,
+        &mut self,
+        corpus_value: &mut GenericCorpusValue,
         rng: &mut dyn rand::Rng,
         only_shrink: bool,
     ) -> anyhow::Result<()>;
@@ -202,7 +324,7 @@
     D: Domain,
     D::CorpusValue: 'static,
 {
-    fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<GenericCorpusValue> {
+    fn init(&mut self, rng: &mut dyn rand::Rng) -> anyhow::Result<GenericCorpusValue> {
         Ok(Box::new(self.init(rng)?))
     }
 
@@ -214,13 +336,13 @@
     ///
     /// See `GenericDomain::mutate` for more details.
     fn mutate(
-        &self,
-        val: &mut GenericCorpusValue,
+        &mut self,
+        corpus_value: &mut GenericCorpusValue,
         rng: &mut dyn rand::Rng,
         only_shrink: bool,
     ) -> anyhow::Result<()> {
         self.mutate(
-            val.downcast_mut().context("Failed to retrieve the Corpus Value")?,
+            corpus_value.downcast_mut().context("Failed to retrieve the Corpus Value")?,
             rng,
             only_shrink,
         )
diff --git a/rust/src/domains/arbitrary.rs b/rust/src/domains/arbitrary.rs
index e2167bf..9e350b8 100644
--- a/rust/src/domains/arbitrary.rs
+++ b/rust/src/domains/arbitrary.rs
@@ -11,13 +11,13 @@
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 // See the License for the specific language governing permissions and
 // limitations under the License.
-
+use super::seeds::DomainSeeds;
+use super::seeds::SeedableDomain;
 use super::utility::choose_value;
 use super::utility::mutate_integer;
 use super::utility::shrink_towards;
 use super::Domain;
 use std::char;
-use std::fmt;
 use std::marker::PhantomData;
 
 use anyhow;
@@ -36,39 +36,38 @@
 /// # use rand::rngs::SmallRng;
 /// # use rand::SeedableRng;
 ///
-/// let arbitrary_i32 = Arbitrary::<i32>::default();
+/// let mut arbitrary_i32 = Arbitrary::<i32>::default();
 /// let mut rng = SmallRng::seed_from_u64(73);
 ///
 /// let sample = arbitrary_i32.init(&mut rng);
 /// assert!(sample.is_ok());
 /// ```
+#[derive(Clone, Debug)]
 pub struct Arbitrary<T> {
+    seeds: DomainSeeds<T>,
     _phantom: PhantomData<T>,
 }
 
-impl<T> Clone for Arbitrary<T> {
-    fn clone(&self) -> Self {
-        Self { _phantom: PhantomData }
-    }
-}
-
-impl<T> fmt::Debug for Arbitrary<T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Arbitrary").field("_phantom", &self._phantom).finish()
-    }
-}
-
 // We cannot just use `#[derive(Default)]` because `T` might not be `Default`.
 impl<T> Default for Arbitrary<T> {
     fn default() -> Self {
-        Self { _phantom: PhantomData }
+        Self { seeds: DomainSeeds::new(), _phantom: PhantomData }
     }
 }
 
 impl<T> Arbitrary<T> {
     /// Creates a new `Arbitrary` domain for the given type `T`.
     pub fn new() -> Self {
-        Self { _phantom: PhantomData }
+        Self::default()
+    }
+}
+
+impl<T: Clone + 'static> SeedableDomain for Arbitrary<T>
+where
+    Arbitrary<T>: Domain<CorpusValue = T>,
+{
+    fn seeds_mut(&mut self) -> &mut DomainSeeds<Self::CorpusValue> {
+        &mut self.seeds
     }
 }
 
@@ -76,12 +75,15 @@
     type UserValue<'user> = bool;
     type CorpusValue = bool;
 
-    fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+    fn init(&mut self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+        if let Some(seed) = self.sample_seed(rng)? {
+            return Ok(seed);
+        }
         Ok(rng.random())
     }
 
     fn mutate(
-        &self,
+        &mut self,
         val: &mut Self::CorpusValue,
         rng: &mut dyn rand::Rng,
         only_shrink: bool,
@@ -101,6 +103,14 @@
     ) -> anyhow::Result<Self::UserValue<'a>> {
         Ok(*corpus_value)
     }
+
+    fn from_value(&self, value: Self::UserValue<'_>) -> anyhow::Result<Self::CorpusValue> {
+        Ok(value)
+    }
+
+    fn validate_corpus_value(&self, _corpus_value: &Self::CorpusValue) -> anyhow::Result<()> {
+        Ok(())
+    }
 }
 
 macro_rules! impl_domain_for_integer {
@@ -112,14 +122,17 @@
             type UserValue<'user> = $ty;
             type CorpusValue = $ty;
 
-            fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
-                // We generate a the equivalent integer type so this works for size types.
+            fn init(&mut self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+                if let Some(seed) = self.sample_seed(rng)? {
+                    return Ok(seed);
+                }
+                // We generate the equivalent integer type so this works for size types.
                 let val: $int_ty = choose_value(rng);
                 Ok(val as $ty)
             }
 
             fn mutate(
-                &self,
+                &mut self,
                 val: &mut Self::CorpusValue,
                 rng: &mut dyn rand::Rng,
                 only_shrink: bool,
@@ -144,6 +157,17 @@
             ) -> anyhow::Result<Self::UserValue<'a>> {
                 Ok(*corpus_value)
             }
+
+            fn from_value(&self, value: Self::UserValue<'_>) -> anyhow::Result<Self::CorpusValue> {
+                Ok(value)
+            }
+
+            fn validate_corpus_value(
+                &self,
+                _corpus_value: &Self::CorpusValue,
+            ) -> anyhow::Result<()> {
+                Ok(())
+            }
         }
     };
 }
@@ -167,12 +191,15 @@
             type UserValue<'user> = $ty;
             type CorpusValue = $ty;
 
-            fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+            fn init(&mut self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+                if let Some(seed) = self.sample_seed(rng)? {
+                    return Ok(seed);
+                }
                 Ok(choose_value(rng))
             }
 
             fn mutate(
-                &self,
+                &mut self,
                 val: &mut Self::CorpusValue,
                 rng: &mut dyn rand::Rng,
                 only_shrink: bool,
@@ -215,6 +242,17 @@
             ) -> anyhow::Result<Self::UserValue<'a>> {
                 Ok(*corpus_value)
             }
+
+            fn from_value(&self, value: Self::UserValue<'_>) -> anyhow::Result<Self::CorpusValue> {
+                Ok(value)
+            }
+
+            fn validate_corpus_value(
+                &self,
+                _corpus_value: &Self::CorpusValue,
+            ) -> anyhow::Result<()> {
+                Ok(())
+            }
         }
     };
 }
@@ -263,12 +301,15 @@
     type UserValue<'user> = char;
     type CorpusValue = char;
 
-    fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+    fn init(&mut self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+        if let Some(seed) = self.sample_seed(rng)? {
+            return Ok(seed);
+        }
         Ok(choose_value(rng))
     }
 
     fn mutate(
-        &self,
+        &mut self,
         val: &mut Self::CorpusValue,
         rng: &mut dyn rand::Rng,
         only_shrink: bool,
@@ -300,18 +341,29 @@
     ) -> anyhow::Result<Self::UserValue<'a>> {
         Ok(*corpus_value)
     }
+
+    fn from_value(&self, value: Self::UserValue<'_>) -> anyhow::Result<Self::CorpusValue> {
+        Ok(value)
+    }
+
+    fn validate_corpus_value(&self, _corpus_value: &Self::CorpusValue) -> anyhow::Result<()> {
+        Ok(())
+    }
 }
 
 impl Domain for Arbitrary<()> {
     type UserValue<'user> = ();
     type CorpusValue = ();
 
-    fn init(&self, _rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+    fn init(&mut self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+        if let Some(seed) = self.sample_seed(rng)? {
+            return Ok(seed);
+        }
         Ok(())
     }
 
     fn mutate(
-        &self,
+        &mut self,
         _val: &mut Self::CorpusValue,
         _rng: &mut dyn rand::Rng,
         _only_shrink: bool,
@@ -326,6 +378,14 @@
     ) -> anyhow::Result<Self::UserValue<'a>> {
         Ok(())
     }
+
+    fn from_value(&self, value: Self::UserValue<'_>) -> anyhow::Result<Self::CorpusValue> {
+        Ok(value)
+    }
+
+    fn validate_corpus_value(&self, _corpus_value: &Self::CorpusValue) -> anyhow::Result<()> {
+        Ok(())
+    }
 }
 
 #[cfg(test)]
@@ -412,7 +472,7 @@
         CorpusValueForArbitrary<T>:
             std::fmt::Debug + Default + Clone + Copy + PartialOrd + PartialEq + 'static,
     {
-        let domain = Arbitrary::<T>::default();
+        let mut domain = Arbitrary::<T>::default();
         let mut rng = get_rng();
         let mut value = domain.init(&mut rng).unwrap();
 
@@ -442,7 +502,7 @@
             + std::hash::Hash
             + 'static,
     {
-        let domain = Arbitrary::<T>::default();
+        let mut domain = Arbitrary::<T>::default();
         let mut rng = get_rng();
         for _ in 0..100 {
             let mut value = domain.init(&mut rng).unwrap();
@@ -474,7 +534,7 @@
             + NumTraitsExtended
             + 'static,
     {
-        let domain = Arbitrary::<T>::default();
+        let mut domain = Arbitrary::<T>::default();
         let mut rng = get_rng();
 
         // Get a value that is not the shrink target
@@ -492,7 +552,8 @@
             domain.mutate(&mut value, &mut rng, true).unwrap();
 
             if value.is_at_shrink_target() {
-                // Ensure that once the shrink target is reached, further shrinking doesn't change it.
+                // Ensure that once the shrink target is reached, further shrinking doesn't change
+                // it.
                 domain.mutate(&mut value, &mut rng, true).unwrap();
                 assert!(
                     value.is_at_shrink_target(),
@@ -619,7 +680,7 @@
     }
 
     fn test_bool_shrink() {
-        let domain = Arbitrary::<bool>::default();
+        let mut domain = Arbitrary::<bool>::default();
         let mut rng = get_rng();
         let mut value = true;
         domain.mutate(&mut value, &mut rng, true).unwrap();
@@ -636,7 +697,7 @@
     #[test]
     fn test_unit() {
         let mut rng = get_rng();
-        let domain = Arbitrary::<()>::default();
+        let mut domain = Arbitrary::<()>::default();
 
         // init() always returns ()
         assert_eq!(domain.init(&mut rng).unwrap(), ());
@@ -659,7 +720,7 @@
             Float + SampleUniform + std::fmt::Display + std::fmt::Debug + SpecialValues + 'static,
         StandardUniform: Distribution<T>,
     {
-        let domain = Arbitrary::<T>::default();
+        let mut domain = Arbitrary::<T>::default();
         let mut rng = get_rng();
 
         // Positive.
@@ -723,7 +784,7 @@
 
     #[test]
     fn test_char_mutate_boundaries() {
-        let domain = Arbitrary::<char>::default();
+        let mut domain = Arbitrary::<char>::default();
         let mut rng = get_rng();
         let mut val = '\u{0000}';
         domain.mutate(&mut val, &mut rng, false).unwrap();
@@ -762,7 +823,7 @@
     #[test]
     fn test_char_shrink_to_null() {
         for _ in 0..10 {
-            let domain = Arbitrary::<char>::default();
+            let mut domain = Arbitrary::<char>::default();
             let mut rng = get_rng();
             let mut value = domain.init(&mut rng).unwrap();
 
diff --git a/rust/src/domains/containers.rs b/rust/src/domains/containers.rs
index a15e28c..40dce2b 100644
--- a/rust/src/domains/containers.rs
+++ b/rust/src/domains/containers.rs
@@ -1,8 +1,7 @@
+use super::Domain;
 use rand::RngExt;
 use std::fmt;
 
-use super::Domain;
-
 const DEFAULT_MAX_LEN: usize = 5000;
 
 macro_rules! choose_one {
@@ -128,7 +127,7 @@
     type CorpusValue = Vec<T::CorpusValue>;
     type UserValue<'user> = Vec<T::UserValue<'user>>;
 
-    fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+    fn init(&mut self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
         if self.max_len() == 0 {
             return Ok(Vec::new());
         }
@@ -143,7 +142,7 @@
     }
 
     fn mutate(
-        &self,
+        &mut self,
         val: &mut Self::CorpusValue,
         rng: &mut dyn rand::Rng,
         only_shrink: bool,
@@ -193,9 +192,40 @@
         }
         Ok(user_values)
     }
+
+    fn from_value(&self, value: Self::UserValue<'_>) -> anyhow::Result<Self::CorpusValue> {
+        let mut corpus_values = Vec::with_capacity(value.len());
+        for item in value {
+            corpus_values.push(self.inner.from_value(item)?);
+        }
+        Ok(corpus_values)
+    }
+
+    fn validate_corpus_value(&self, corpus_value: &Self::CorpusValue) -> anyhow::Result<()> {
+        if self.max_len_is_soft {
+            anyhow::ensure!(
+                self.min_len <= corpus_value.len(),
+                "Length {} is less than the minimum length {}",
+                corpus_value.len(),
+                self.min_len
+            );
+        } else {
+            anyhow::ensure!(
+                self.min_len <= corpus_value.len() && corpus_value.len() <= self.max_len(),
+                "Length {} is not between the minimum length {} and maximum length {}",
+                corpus_value.len(),
+                self.min_len,
+                self.max_len()
+            );
+        }
+        for item in corpus_value {
+            self.inner.validate_corpus_value(item)?;
+        }
+        Ok(())
+    }
 }
 
-impl<T> ContainerDomain for VecOf<T> {
+impl<T: Domain> ContainerDomain for VecOf<T> {
     fn with_len(self, len: usize) -> Self {
         Self { min_len: len, max_len: Some(len), ..self }
     }
@@ -245,7 +275,7 @@
 
     #[gtest]
     fn test_vec_of_mutate_shrink() {
-        let domain = VecOf::new(Arbitrary::<u32>::default()).with_max_len(10);
+        let mut domain = VecOf::new(Arbitrary::<u32>::default()).with_max_len(10);
 
         let mut rng = get_rng();
 
@@ -264,7 +294,7 @@
 
     #[gtest]
     fn test_vec_of_mutate_grow_and_change() {
-        let domain = VecOf::new(Arbitrary::<u32>::default()).with_max_len(10);
+        let mut domain = VecOf::new(Arbitrary::<u32>::default()).with_max_len(10);
 
         let mut rng = get_rng();
 
@@ -284,7 +314,7 @@
 
     #[gtest]
     fn test_vec_of_init_respects_min_len() {
-        let domain = VecOf::new(Arbitrary::<u32>::default()).with_min_len(5);
+        let mut domain = VecOf::new(Arbitrary::<u32>::default()).with_min_len(5);
         let mut rng = get_rng();
 
         for _ in 0..100 {
@@ -295,7 +325,7 @@
 
     #[gtest]
     fn test_vec_of_init_fixed_len() {
-        let domain = VecOf::new(Arbitrary::<u32>::default()).with_len(7);
+        let mut domain = VecOf::new(Arbitrary::<u32>::default()).with_len(7);
         let mut rng = get_rng();
 
         for _ in 0..100 {
@@ -306,7 +336,7 @@
 
     #[gtest]
     fn test_vec_of_init_default_max_len() {
-        let domain = VecOf::new(Arbitrary::<u32>::default());
+        let mut domain = VecOf::new(Arbitrary::<u32>::default());
         let mut rng = get_rng();
 
         for _ in 0..100 {
@@ -317,7 +347,7 @@
 
     #[gtest]
     fn test_vec_of_mutate_respects_min_len() {
-        let domain = VecOf::new(Arbitrary::<u32>::default()).with_min_len(3);
+        let mut domain = VecOf::new(Arbitrary::<u32>::default()).with_min_len(3);
         let mut rng = get_rng();
 
         let mut val = vec![1, 2, 3];
@@ -329,7 +359,7 @@
 
     #[gtest]
     fn test_vec_of_mutate_respects_max_len() {
-        let domain = VecOf::new(Arbitrary::<u32>::default()).with_max_len(3);
+        let mut domain = VecOf::new(Arbitrary::<u32>::default()).with_max_len(3);
         let mut rng = get_rng();
 
         let mut val = vec![1, 2, 3];
@@ -341,7 +371,7 @@
 
     #[gtest]
     fn test_vec_of_mutate_min_len_validation() {
-        let domain = VecOf::new(Arbitrary::<u32>::default()).with_min_len(5);
+        let mut domain = VecOf::new(Arbitrary::<u32>::default()).with_min_len(5);
         let mut rng = get_rng();
 
         let mut val = vec![1, 2, 3]; // Length 3, which is < 5
@@ -358,7 +388,7 @@
 
     #[gtest]
     fn test_vec_of_mutate_soft_max_len_behavior() {
-        let domain = VecOf::new(Arbitrary::<u32>::default()).with_soft_max_len(5);
+        let mut domain = VecOf::new(Arbitrary::<u32>::default()).with_soft_max_len(5);
         let mut rng = get_rng();
 
         // Valid mutation within bounds
@@ -394,7 +424,7 @@
 
     #[gtest]
     fn test_vec_of_mutate_no_action_at_bounds() {
-        let domain = VecOf::new(Arbitrary::<u32>::default()).with_len(1);
+        let mut domain = VecOf::new(Arbitrary::<u32>::default()).with_len(1);
         let mut rng = get_rng();
 
         let mut val = vec![100u32];
@@ -415,7 +445,7 @@
 
     #[gtest]
     fn test_vec_of_zero_len() {
-        let domain = VecOf::new(Arbitrary::<u32>::default()).with_len(0);
+        let mut domain = VecOf::new(Arbitrary::<u32>::default()).with_len(0);
         let mut rng = get_rng();
 
         let val = domain.init(&mut rng).unwrap();
diff --git a/rust/src/domains/range.rs b/rust/src/domains/range.rs
index 3bf413b..c9ad1c7 100644
--- a/rust/src/domains/range.rs
+++ b/rust/src/domains/range.rs
@@ -57,12 +57,12 @@
     type UserValue<'user> = i32;
     type CorpusValue = i32;
 
-    fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+    fn init(&mut self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
         Ok(self.get_in_range(rng))
     }
 
     fn mutate(
-        &self,
+        &mut self,
         val: &mut Self::CorpusValue,
         rng: &mut dyn rand::Rng,
         only_shrink: bool,
@@ -81,6 +81,22 @@
     ) -> anyhow::Result<Self::UserValue<'a>> {
         Ok(*corpus_value)
     }
+
+    fn from_value(&self, value: Self::UserValue<'_>) -> anyhow::Result<Self::CorpusValue> {
+        Ok(value)
+    }
+
+    fn validate_corpus_value(&self, corpus_value: &Self::CorpusValue) -> anyhow::Result<()> {
+        if *corpus_value < self.lower || *corpus_value > self.upper {
+            anyhow::bail!(
+                "Value {} is out of range [{}, {}]",
+                corpus_value,
+                self.lower,
+                self.upper
+            );
+        }
+        Ok(())
+    }
 }
 
 #[cfg(test)]
diff --git a/rust/src/internal.rs b/rust/src/internal.rs
index 213e66a..5f7e95b 100644
--- a/rust/src/internal.rs
+++ b/rust/src/internal.rs
@@ -14,8 +14,11 @@
 
 use super::domains::GenericCorpusValue;
 use super::domains::GenericDomain;
+
 use std::collections::HashMap;
+use std::sync::Arc;
 use std::sync::LazyLock;
+use std::sync::Mutex;
 
 /// A trait implemented by types used to Fuzz a given property function.
 ///
@@ -35,7 +38,7 @@
     /// Returns `true` if the property function holds, `false` if it crashes.
     fn execute(&self, args: &GenericCorpusValue) -> bool;
     fn print_finding_report(&self);
-    fn domains(&self) -> &dyn GenericDomain;
+    fn domains(&self) -> Arc<Mutex<dyn GenericDomain>>;
 }
 
 /// Identifies the property function of a fuzz test.
diff --git a/rust/src/worker.rs b/rust/src/worker.rs
index e19f21f..cd9ed80 100644
--- a/rust/src/worker.rs
+++ b/rust/src/worker.rs
@@ -158,7 +158,9 @@
     }
 
     pub fn get_random_seed_input(&self, sink: &mut InputSink) {
-        match self.fuzz_test.domains().init(&mut rand::rng()) {
+        let domains = self.fuzz_test.domains();
+        let mut domains_guard = domains.lock().expect("Failed to lock domains");
+        match domains_guard.init(&mut rand::rng()) {
             Ok(val) => {
                 sink.emit(pack_input(val));
             }
@@ -170,8 +172,10 @@
 
     pub fn mutate(&self, origin: &GenericCorpusValue, shrink: bool, sink: &mut InputSink) {
         let mut mutant = origin.clone();
+        let domains = self.fuzz_test.domains();
+        let mut domains_guard = domains.lock().expect("Failed to lock domains");
 
-        if let Err(e) = self.fuzz_test.domains().mutate(&mut mutant, &mut rand::rng(), shrink) {
+        if let Err(e) = domains_guard.mutate(&mut mutant, &mut rand::rng(), shrink) {
             emit_error(&format!("Failed to mutate: {:?}", e));
             return;
         }
@@ -211,7 +215,9 @@
     }
 
     pub fn serialize_input_content(&self, input: &GenericCorpusValue, sink: &mut BytesSink) {
-        match self.fuzz_test.domains().serialize_corpus(input) {
+        let domains = self.fuzz_test.domains();
+        let domains_guard = domains.lock().expect("Failed to lock domains");
+        match domains_guard.serialize_corpus(input) {
             Ok(serialized) => {
                 sink.emit(&serialized);
             }
@@ -222,7 +228,9 @@
     }
 
     pub fn deserialize_input_content(&self, content: &[u8], sink: &mut InputSink) {
-        match self.fuzz_test.domains().parse_corpus(content) {
+        let domains = self.fuzz_test.domains();
+        let domains_guard = domains.lock().expect("Failed to lock domains");
+        match domains_guard.parse_corpus(content) {
             Ok(val) => {
                 sink.emit(pack_input(val));
             }
@@ -242,8 +250,9 @@
 
     pub fn free_input(&self, input: engine_ffi::FuzzTestInputHandle) {
         if input.0 != 0 {
-            // SAFETY: The engine guarantees `input` was created by `deserialize_input_content_callback`
-            // (or `emit` in `InputSink`) and has not been freed yet.
+            // SAFETY: The engine guarantees `input` was created by
+            // `deserialize_input_content_callback` (or `emit` in `InputSink`) and has
+            // not been freed yet.
             unsafe {
                 let _ = Box::from_raw(input.0 as *mut GenericCorpusValue);
             }
@@ -292,8 +301,8 @@
 ///
 /// The caller must ensure that:
 /// * `ctx` is a valid pointer to the `RustFuzzTestAdapterManager` passed during initialization.
-/// * `sink` is a valid pointer to a `FuzzTestBytesSink` whose lifetime extends for the duration
-///   of this call.
+/// * `sink` is a valid pointer to a `FuzzTestBytesSink` whose lifetime extends for the duration of
+///   this call.
 pub unsafe extern "C" fn get_binary_id_callback(
     ctx: *mut engine_ffi::FuzzTestAdapterManagerCtx,
     sink: *const engine_ffi::FuzzTestBytesSink,
@@ -311,8 +320,8 @@
 ///
 /// The caller must ensure that:
 /// * `ctx` is a valid pointer to the `RustFuzzTestAdapterManager` passed during initialization.
-/// * `sink` is a valid pointer to a `FuzzTestBytesSink` whose lifetime extends for the duration
-///   of this call.
+/// * `sink` is a valid pointer to a `FuzzTestBytesSink` whose lifetime extends for the duration of
+///   this call.
 pub unsafe extern "C" fn get_test_name_callback(
     ctx: *mut engine_ffi::FuzzTestAdapterManagerCtx,
     sink: *const engine_ffi::FuzzTestBytesSink,
@@ -342,8 +351,8 @@
     // passed during initialization.
     let manager = unsafe { &*(ctx as *const RustFuzzTestAdapterManager) };
 
-    // SAFETY: The engine guarantees `diagnostic_sink` is a valid pointer to a `FuzzTestDiagnosticSink`
-    // whose lifetime extends until `FreeCtx` is called on the adapter.
+    // SAFETY: The engine guarantees `diagnostic_sink` is a valid pointer to a
+    // `FuzzTestDiagnosticSink` whose lifetime extends until `FreeCtx` is called on the adapter.
     let safe_sink = unsafe { DiagnosticSink::from_raw(diagnostic_sink) };
 
     set_diagnostic_sink(safe_sink);
@@ -387,7 +396,8 @@
     // SAFETY: The engine guarantees `ctx` is a valid pointer to the `RustFuzzTestAdapter`
     // created by `construct_adapter_callback`.
     let adapter = unsafe { &*(ctx as *const RustFuzzTestAdapter) };
-    // SAFETY: The engine guarantees `registry` is a valid pointer to `FuzzTestCoverageDomainRegistry`.
+    // SAFETY: The engine guarantees `registry` is a valid pointer to
+    // `FuzzTestCoverageDomainRegistry`.
     let mut registry = unsafe { CoverageDomainRegistry::from_raw(registry) };
     adapter.set_up_coverage_domains(&mut registry);
 }
@@ -577,7 +587,8 @@
 /// * `ctx` is a valid pointer to the `RustFuzzTestAdapter` created by `construct_adapter_callback`.
 /// * `metadata` is a valid pointer to `FuzzTestBytesView` containing serialized input metadata.
 /// * `input` is a valid `FuzzTestInputHandle` pointing to a heap-allocated `GenericCorpusValue`
-///   managed by the framework, and the engine guarantees exclusive access to it for the call duration.
+///   managed by the framework, and the engine guarantees exclusive access to it for the call
+///   duration.
 pub unsafe extern "C" fn update_input_metadata_callback(
     ctx: *mut engine_ffi::FuzzTestAdapterCtx,
     metadata: *const engine_ffi::FuzzTestBytesView,
@@ -639,6 +650,8 @@
 
     let mut generic_corpus_value = fuzztest
         .domains()
+        .lock()
+        .expect("Failed to lock domains")
         .init(&mut rng)
         .expect("domain initialization should succeed to provide an initial corpus value");
 
@@ -649,6 +662,8 @@
     while start_time.elapsed() < smoke_test_duration {
         fuzztest
             .domains()
+            .lock()
+            .expect("Failed to lock domains")
             .mutate(&mut generic_corpus_value, &mut rng, only_shrink)
             .expect("domain mutation should succeed");
         let result = fuzztest.execute(&generic_corpus_value);
@@ -673,9 +688,9 @@
 ///      engine loop until complete.
 ///    - Returns cleanly on [`WorkerStatus::Success`], or panics on [`WorkerStatus::Failure`] to
 ///      signal test failure to the harness.
-/// 2. Smoke Test Mode: If worker mode is not active (e.g., during standard `blaze test` or
-///    `cargo test` unit test runs), falls back to executing a short local smoke test using sample
-///    inputs and mutation iterations to verify property function sanity.
+/// 2. Smoke Test Mode: If worker mode is not active (e.g., during standard `blaze test` or `cargo
+///    test` unit test runs), falls back to executing a short local smoke test using sample inputs
+///    and mutation iterations to verify property function sanity.
 pub fn process(manager: RustFuzzTestAdapterManager) {
     super::crash_handler::register_crash_handler();
 
diff --git a/rust/tests/macro_compiles.rs b/rust/tests/macro_compiles.rs
index 04c245e..e77615e 100644
--- a/rust/tests/macro_compiles.rs
+++ b/rust/tests/macro_compiles.rs
@@ -15,6 +15,7 @@
 use fuzztest::domains::arbitrary::Arbitrary;
 use fuzztest::domains::containers::ContainerDomain;
 use fuzztest::domains::containers::VecOf;
+use fuzztest::domains::seeds::SeedableDomain;
 use fuzztest::fuzztest;
 
 #[fuzztest(_a = Arbitrary::<i32>::default())]
@@ -26,6 +27,12 @@
 #[fuzztest(_a = VecOf::new(Arbitrary::<i32>::default()).with_max_len(10))]
 fn fuzztest_macro_compiles_with_vec(_a: Vec<i32>) {}
 
+#[fuzztest(_a = Arbitrary::<i32>::default().with_seeds([1, 2, 3]))]
+fn fuzztest_macro_compiles_with_seeds(_a: i32) {}
+
+#[fuzztest(_a = Arbitrary::<i32>::default().with_seed_provider(|| vec![1, 2, 3]))]
+fn fuzztest_macro_compiles_with_seed_provider(_a: i32) {}
+
 fn main() {
     // The property function is defined in the scope where the macro is
     // invoked, so it can be called directly, e.g. from a regression test.