diff --git a/src/arbitrary.rs b/src/arbitrary.rs index 018cb4c..beec475 100644 --- a/src/arbitrary.rs +++ b/src/arbitrary.rs @@ -105,12 +105,21 @@ fn expr_for_enum(input: &DeriveInput, data: &DataEnum, bounds: &mut Bounds) -> R let args: ArbitraryArgsForFieldOrVariant = parse_from_attrs(&variant.attrs, "arbitrary")?; let mut weight = None; for attr in &variant.attrs { - if attr.path().is_ident("weight") { + let Some(ident) = attr.path().get_ident() else { + continue; + }; + if ident == "weight" { if weight.is_some() { bail!(attr.span(), "`#[weight]` can specify only once."); } weight = Some(attr.parse_args::()?); } + if ident == "any" || ident == "strategy" || ident == "map" || ident == "by_ref" { + bail!( + attr.span(), + "`#[{ident}]` cannot be specified for a variant. Consider specifying it for a field instead." + ); + } } let weight = if let Some(arg) = weight { if arg.is_zero() { diff --git a/src/syn_utils.rs b/src/syn_utils.rs index ab398ae..974a299 100644 --- a/src/syn_utils.rs +++ b/src/syn_utils.rs @@ -20,14 +20,14 @@ use syn::{ }; macro_rules! bail { - ($span:expr, $message:literal $(,)?) => { - return std::result::Result::Err(syn::Error::new($span, $message)) + (_, $($arg:tt)*) => { + bail!(::proc_macro2::Span::call_site(), $($arg)*) }; - ($span:expr, $err:expr $(,)?) => { - return std::result::Result::Err(syn::Error::new($span, $err)) + ($span:expr, $fmt:literal $(,)?) => { + return ::std::result::Result::Err(::syn::Error::new($span, ::std::format!($fmt))) }; - ($span:expr, $fmt:expr, $($arg:tt)*) => { - return std::result::Result::Err(syn::Error::new($span, std::format!($fmt, $($arg)*))) + ($span:expr, $fmt:literal, $($arg:tt)*) => { + return ::std::result::Result::Err(::syn::Error::new($span, ::std::format!($fmt, $($arg)*))) }; } diff --git a/tests/compile_fail/variant_any_attr.rs b/tests/compile_fail/variant_any_attr.rs new file mode 100644 index 0000000..25bc146 --- /dev/null +++ b/tests/compile_fail/variant_any_attr.rs @@ -0,0 +1,8 @@ +use test_strategy::Arbitrary; +#[derive(Arbitrary, Debug)] +enum X { + #[any] + A, +} + +fn main() {} diff --git a/tests/compile_fail/variant_any_attr.stderr b/tests/compile_fail/variant_any_attr.stderr new file mode 100644 index 0000000..a95cf88 --- /dev/null +++ b/tests/compile_fail/variant_any_attr.stderr @@ -0,0 +1,5 @@ +error: `#[any]` cannot be specified for a variant. Consider specifying it for a field instead. + --> tests/compile_fail/variant_any_attr.rs:4:5 + | +4 | #[any] + | ^ diff --git a/tests/compile_fail/variant_strategy_attr.rs b/tests/compile_fail/variant_strategy_attr.rs new file mode 100644 index 0000000..173a3f2 --- /dev/null +++ b/tests/compile_fail/variant_strategy_attr.rs @@ -0,0 +1,8 @@ +use test_strategy::Arbitrary; +#[derive(Arbitrary, Debug)] +enum X { + #[strategy(0..10usize)] + A(usize), +} + +fn main() {} diff --git a/tests/compile_fail/variant_strategy_attr.stderr b/tests/compile_fail/variant_strategy_attr.stderr new file mode 100644 index 0000000..fc7fb27 --- /dev/null +++ b/tests/compile_fail/variant_strategy_attr.stderr @@ -0,0 +1,5 @@ +error: `#[strategy]` cannot be specified for a variant. Consider specifying it for a field instead. + --> tests/compile_fail/variant_strategy_attr.rs:4:5 + | +4 | #[strategy(0..10usize)] + | ^