No public description

PiperOrigin-RevId: 1007464051
diff --git a/rust/cargo_fuzztest/test_crates/another_sample_fuzz_crate/src/lib.rs b/rust/cargo_fuzztest/test_crates/another_sample_fuzz_crate/src/lib.rs
index 0995410..6aea48a 100644
--- a/rust/cargo_fuzztest/test_crates/another_sample_fuzz_crate/src/lib.rs
+++ b/rust/cargo_fuzztest/test_crates/another_sample_fuzz_crate/src/lib.rs
@@ -11,7 +11,7 @@
     let _ = data;
 }
 
-#[fuzztest(data = Arbitrary::<i32>::default())]
+#[fuzztest(_data = Arbitrary::<i32>::default())]
 fn jobs_fuzztest_target(_data: i32) {
     println!("JOBS_TEST_PID: {}", std::process::id());
 }
diff --git a/rust/e2e_tests/testdata/fuzz_tests.rs b/rust/e2e_tests/testdata/fuzz_tests.rs
index e725ff9..cfedd96 100644
--- a/rust/e2e_tests/testdata/fuzz_tests.rs
+++ b/rust/e2e_tests/testdata/fuzz_tests.rs
@@ -181,5 +181,5 @@
     }
 }
 
-#[fuzztest(a = FallibleDomain::new())]
+#[fuzztest(_a = FallibleDomain::new())]
 fn fallible_fuzz_test(_a: u32) {}
diff --git a/rust/fuzztest_macro/src/helpers/test_registration.rs b/rust/fuzztest_macro/src/helpers/test_registration.rs
index a17af8e..7fe486d 100644
--- a/rust/fuzztest_macro/src/helpers/test_registration.rs
+++ b/rust/fuzztest_macro/src/helpers/test_registration.rs
@@ -17,6 +17,8 @@
 use proc_macro2::Span;
 use proc_macro2::TokenStream;
 use quote::quote;
+use syn::parse::Parse;
+use syn::parse::ParseStream;
 use syn::parse_quote;
 use syn::Expr;
 use syn::Generics;
@@ -33,6 +35,19 @@
 const USER_VALUE_LIFETIME_GENERIC_NAME: &str = "'user";
 
 #[derive(Clone, Debug)]
+pub struct FuzzTestArg {
+    pub ident: Ident,
+    pub _eq_token: syn::Token![=],
+    pub domain_ty: Expr,
+}
+
+impl Parse for FuzzTestArg {
+    fn parse(input: ParseStream) -> syn::Result<Self> {
+        Ok(Self { ident: input.parse()?, _eq_token: input.parse()?, domain_ty: input.parse()? })
+    }
+}
+
+#[derive(Clone, Debug)]
 pub struct FuzzTestObjectDefinitionAndFactory {
     pub fuzztest_object_factory_name: Ident,
     pub fuzztest_object_tokenstream: TokenStream,
@@ -68,7 +83,7 @@
     /// pre-computes the tokenstream for the fuzz test struct instance.
     pub fn new(
         test_fn_signature: &'a Signature,
-        domain_ctors: impl IntoIterator<Item = &'a Expr>,
+        fuzztest_args: impl IntoIterator<Item = &'a FuzzTestArg>,
     ) -> syn::Result<Self> {
         let user_value_lifetime_generic =
             Lifetime::new(USER_VALUE_LIFETIME_GENERIC_NAME, Span::call_site());
@@ -91,9 +106,33 @@
             ));
         }
 
+        let fuzztest_args = fuzztest_args.into_iter().collect::<Vec<_>>();
+        if fuzztest_args.len() != test_fn_args.len() {
+            return Err(syn::Error::new_spanned(
+                test_fn_signature,
+                format!(
+                    "number of domain arguments in #[fuzztest] ({}) does not match number of property function parameters ({})",
+                    fuzztest_args.len(),
+                    test_fn_args.len()
+                ),
+            ));
+        }
+
+        for (fuzztest_arg, test_fn_arg) in fuzztest_args.iter().zip(&test_fn_args) {
+            if fuzztest_arg.ident != *test_fn_arg.name {
+                return Err(syn::Error::new_spanned(
+                    &fuzztest_arg.ident,
+                    format!(
+                        "domain argument name `{}` does not match property function parameter name `{}`",
+                        fuzztest_arg.ident, test_fn_arg.name
+                    ),
+                ));
+            }
+        }
+
         let test_fn_ident = &test_fn_signature.ident;
         let prop_fn_ident = quote::format_ident!("__property_fn__{}", test_fn_ident);
-        let domain_ctors = domain_ctors.into_iter().collect::<Vec<_>>();
+        let domain_ctors = fuzztest_args.iter().map(|arg| &arg.domain_ty).collect::<Vec<_>>();
         let fuzz_test_struct_name =
             quote::format_ident!("__FuzzTest{}", test_fn_ident.to_string().to_case(Case::Pascal));
         let crate_name = import_fuzztest_crate();
@@ -283,11 +322,11 @@
     #[googletest::test]
     fn test_generate_test_registration() {
         let sig: Signature = parse_quote! { fn test_fuzz(a: i32, b: std::string::String) };
-        let expr1: Expr =
-            parse_quote! { ::fuzztest::domains::arbitrary::Arbitrary::<i32>::default() };
-        let expr2: Expr =
-            parse_quote! { ::fuzztest::domains::arbitrary::Arbitrary::<String>::default() };
-        let context = FuzzTestRegistrationCtx::new(&sig, [&expr1, &expr2]).unwrap();
+        let arg1: FuzzTestArg =
+            parse_quote! { a = ::fuzztest::domains::arbitrary::Arbitrary::<i32>::default() };
+        let arg2: FuzzTestArg =
+            parse_quote! { b = ::fuzztest::domains::arbitrary::Arbitrary::<String>::default() };
+        let context = FuzzTestRegistrationCtx::new(&sig, [&arg1, &arg2]).unwrap();
         let FuzzTestObjectDefinitionAndFactory {
             fuzztest_object_factory_name,
             fuzztest_object_tokenstream,
@@ -360,11 +399,11 @@
     #[googletest::test]
     fn test_generate_gtest() {
         let sig: Signature = parse_quote! { fn test_fuzz(a: i32, b: std::string::String) };
-        let expr1: Expr =
-            parse_quote! { ::fuzztest::domains::arbitrary::Arbitrary::<i32>::default() };
-        let expr2: Expr =
-            parse_quote! { ::fuzztest::domains::arbitrary::Arbitrary::<String>::default() };
-        let context = FuzzTestRegistrationCtx::new(&sig, [&expr1, &expr2]).unwrap();
+        let arg1: FuzzTestArg =
+            parse_quote! { a = ::fuzztest::domains::arbitrary::Arbitrary::<i32>::default() };
+        let arg2: FuzzTestArg =
+            parse_quote! { b = ::fuzztest::domains::arbitrary::Arbitrary::<String>::default() };
+        let context = FuzzTestRegistrationCtx::new(&sig, [&arg1, &arg2]).unwrap();
         let GTestDefinition { gtest_tokens } = context.generate_gtest().unwrap();
 
         // test that the gtest was generated
@@ -390,4 +429,36 @@
             )
         )
     }
+
+    #[googletest::test]
+    fn test_mismatched_argument_count_fails() {
+        let sig: Signature = parse_quote! { fn test_fuzz(a: i32, b: std::string::String) };
+        let arg1: FuzzTestArg =
+            parse_quote! { a = ::fuzztest::domains::arbitrary::Arbitrary::<i32>::default() };
+
+        let err = FuzzTestRegistrationCtx::new(&sig, [&arg1]).err().unwrap();
+        expect_that!(
+            err.to_string(),
+            matchers::contains_substring(
+                "number of domain arguments in #[fuzztest] (1) does not match number of property function parameters (2)"
+            )
+        );
+    }
+
+    #[googletest::test]
+    fn test_mismatched_argument_name_fails() {
+        let sig: Signature = parse_quote! { fn test_fuzz(a: i32, b: std::string::String) };
+        let arg1: FuzzTestArg =
+            parse_quote! { a = ::fuzztest::domains::arbitrary::Arbitrary::<i32>::default() };
+        let arg2: FuzzTestArg =
+            parse_quote! { wrong_name = ::fuzztest::domains::arbitrary::Arbitrary::<String>::default() };
+
+        let err = FuzzTestRegistrationCtx::new(&sig, [&arg1, &arg2]).err().unwrap();
+        expect_that!(
+            err.to_string(),
+            matchers::contains_substring(
+                "domain argument name `wrong_name` does not match property function parameter name `b`"
+            )
+        );
+    }
 }
diff --git a/rust/fuzztest_macro/src/lib.rs b/rust/fuzztest_macro/src/lib.rs
index d51935a..a8b5f89 100644
--- a/rust/fuzztest_macro/src/lib.rs
+++ b/rust/fuzztest_macro/src/lib.rs
@@ -20,26 +20,14 @@
 use proc_macro::TokenStream;
 
 use quote::quote;
-use syn::parse::{Parse, ParseStream, Parser};
+use syn::parse::Parser;
 use syn::{parse_macro_input, Item};
 
+use helpers::test_registration::FuzzTestArg;
 use helpers::test_registration::FuzzTestObjectDefinitionAndFactory;
 use helpers::test_registration::FuzzTestRegistrationCtx;
 use helpers::test_registration::GTestDefinition;
 
-#[derive(Debug)]
-struct FuzzTestArg {
-    _ident: syn::Ident,
-    _eq_token: syn::Token![=],
-    domain_ty: syn::Expr,
-}
-
-impl Parse for FuzzTestArg {
-    fn parse(input: ParseStream) -> syn::Result<Self> {
-        Ok(Self { _ident: input.parse()?, _eq_token: input.parse()?, domain_ty: input.parse()? })
-    }
-}
-
 /// The `fuzztest` macro is used to generate and register a fuzz test object to be used by a fuzz
 /// testing engine.
 ///
@@ -81,10 +69,8 @@
         Err(e) => return e.into_compile_error().into(),
     };
 
-    let domain_ctors = args.iter().map(|arg| &arg.domain_ty);
-
     let fuzztest_registration_context =
-        match FuzzTestRegistrationCtx::new(&test_fn.sig, domain_ctors) {
+        match FuzzTestRegistrationCtx::new(&test_fn.sig, &args) {
             Ok(fuzztest_registration_context) => fuzztest_registration_context,
             Err(e) => return e.into_compile_error().into(),
         };