diff --git a/pyo3-macros-backend/src/method.rs b/pyo3-macros-backend/src/method.rs index 9b40ac00..6088a2cd 100644 --- a/pyo3-macros-backend/src/method.rs +++ b/pyo3-macros-backend/src/method.rs @@ -40,14 +40,14 @@ impl<'a> FnArg<'a> { } let arg_attrs = PyFunctionArgPyO3Attributes::from_attrs(&mut cap.attrs)?; - let (ident, by_ref, mutability) = match *cap.pat { + let (ident, by_ref, mutability) = match &*cap.pat { syn::Pat::Ident(syn::PatIdent { - ref ident, - ref by_ref, - ref mutability, + ident, + by_ref, + mutability, .. }) => (ident, by_ref, mutability), - _ => bail_spanned!(cap.pat.span() => "unsupported argument"), + other => return Err(handle_argument_error(other)), }; Ok(FnArg { @@ -67,6 +67,19 @@ impl<'a> FnArg<'a> { } } +fn handle_argument_error(pat: &syn::Pat) -> syn::Error { + let span = pat.span(); + let msg = match pat { + syn::Pat::Wild(_) => "wildcard argument names are not supported", + syn::Pat::Struct(_) + | syn::Pat::Tuple(_) + | syn::Pat::TupleStruct(_) + | syn::Pat::Slice(_) => "destructuring in arguments is not supported", + _ => "unsupported argument", + }; + syn::Error::new(span, msg) +} + #[derive(Clone, PartialEq, Debug, Copy, Eq)] pub enum MethodTypeAttribute { /// `#[new]` diff --git a/tests/ui/invalid_pyfunctions.rs b/tests/ui/invalid_pyfunctions.rs index 680ca56e..7ddad156 100644 --- a/tests/ui/invalid_pyfunctions.rs +++ b/tests/ui/invalid_pyfunctions.rs @@ -9,4 +9,10 @@ fn impl_trait_function(impl_trait: impl AsRef) {} #[pyfunction] async fn async_function() {} +#[pyfunction] +fn wildcard_argument(_: i32) {} + +#[pyfunction] +fn destructured_argument((a, b): (i32, i32)) {} + fn main() {} diff --git a/tests/ui/invalid_pyfunctions.stderr b/tests/ui/invalid_pyfunctions.stderr index 6587535a..a44f208c 100644 --- a/tests/ui/invalid_pyfunctions.stderr +++ b/tests/ui/invalid_pyfunctions.stderr @@ -17,3 +17,15 @@ error: `async fn` is not yet supported for Python functions. | 10 | async fn async_function() {} | ^^^^^ + +error: wildcard argument names are not supported + --> tests/ui/invalid_pyfunctions.rs:13:22 + | +13 | fn wildcard_argument(_: i32) {} + | ^ + +error: destructuring in arguments is not supported + --> tests/ui/invalid_pyfunctions.rs:16:26 + | +16 | fn destructured_argument((a, b): (i32, i32)) {} + | ^^^^^^