From aa899f9520b1e861af5ae0debc2067f5b0926838 Mon Sep 17 00:00:00 2001 From: Casper Meijn Date: Tue, 10 Sep 2024 11:51:01 +0200 Subject: [PATCH] fix(derive): allow `derive(Arbitrary)` for `struct Option` Use the full path to `core::option::Option` and `core::default::Default` in the generated code. This allows `derive(Arbitrary)` on structs named `Option` or `Default`. --- derive/src/lib.rs | 8 ++++---- tests/derive.rs | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 33b6417..9aec119 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -341,7 +341,7 @@ fn construct( fn construct_take_rest(fields: &Fields) -> Result { construct(fields, |idx, field| { determine_field_constructor(field).map(|field_constructor| match field_constructor { - FieldConstructor::Default => quote!(Default::default()), + FieldConstructor::Default => quote!(::core::default::Default::default()), FieldConstructor::Arbitrary => { if idx + 1 == fields.len() { quote! { arbitrary::Arbitrary::arbitrary_take_rest(u)? } @@ -392,7 +392,7 @@ fn gen_size_hint_method(input: &DeriveInput) -> Result { size_hint_fields(fields).map(|hint| { quote! { #[inline] - fn size_hint(depth: usize) -> (usize, Option) { + fn size_hint(depth: usize) -> (usize, ::core::option::Option) { arbitrary::size_hint::recursion_guard(depth, |depth| #hint) } } @@ -414,7 +414,7 @@ fn gen_size_hint_method(input: &DeriveInput) -> Result { .map(|variants| { quote! { #[inline] - fn size_hint(depth: usize) -> (usize, Option) { + fn size_hint(depth: usize) -> (usize, ::core::option::Option) { arbitrary::size_hint::and( ::size_hint(depth), arbitrary::size_hint::recursion_guard(depth, |depth| { @@ -429,7 +429,7 @@ fn gen_size_hint_method(input: &DeriveInput) -> Result { fn gen_constructor_for_field(field: &Field) -> Result { let ctor = match determine_field_constructor(field)? { - FieldConstructor::Default => quote!(Default::default()), + FieldConstructor::Default => quote!(::core::default::Default::default()), FieldConstructor::Arbitrary => quote!(arbitrary::Arbitrary::arbitrary(u)?), FieldConstructor::With(function_or_closure) => quote!((#function_or_closure)(u)?), FieldConstructor::Value(value) => quote!(#value), diff --git a/tests/derive.rs b/tests/derive.rs index b73da11..bca6cfe 100644 --- a/tests/derive.rs +++ b/tests/derive.rs @@ -300,3 +300,20 @@ fn test_field_attributes() { // 17 is the 3rd byte used by arbitrary assert_eq!(parcel.price, 17); } + +#[test] +fn derive_structs_named_same_as_core() { + #[derive(Debug, Arbitrary)] + struct Option { + f: core::option::Option, + } + + let _ = Option::arbitrary(&mut Unstructured::new(&[])); + + #[derive(Debug, Default, Arbitrary)] + struct Default { + f: u32, + } + + let _ = Default::arbitrary(&mut Unstructured::new(&[])); +}