From 35f53016759e7221237550a9bdce3342344f63a0 Mon Sep 17 00:00:00 2001 From: kngwyu Date: Tue, 4 Jun 2019 14:17:07 +0900 Subject: [PATCH] Reject generics explicitly for #[pyclass] --- Cargo.toml | 1 + pyo3-derive-backend/src/pyclass.rs | 12 ++++++++++++ tests/test_compile_error.rs | 6 ++++++ tests/ui/reject_generics.rs | 8 ++++++++ tests/ui/reject_generics.stderr | 5 +++++ 5 files changed, 32 insertions(+) create mode 100644 tests/test_compile_error.rs create mode 100644 tests/ui/reject_generics.rs create mode 100644 tests/ui/reject_generics.stderr diff --git a/Cargo.toml b/Cargo.toml index 8330905d..fbdf69b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ inventory = "0.1.3" [dev-dependencies] assert_approx_eq = "1.1.0" indoc = "0.3.3" +trybuild = "1.0" [build-dependencies] regex = "1.1.6" diff --git a/pyo3-derive-backend/src/pyclass.rs b/pyo3-derive-backend/src/pyclass.rs index 04f37868..cbd4fbfc 100644 --- a/pyo3-derive-backend/src/pyclass.rs +++ b/pyo3-derive-backend/src/pyclass.rs @@ -154,6 +154,7 @@ pub fn build_py_class(class: &mut syn::ItemStruct, attr: &PyClassArgs) -> syn::R let doc = utils::get_doc(&class.attrs, true); let mut descriptors = Vec::new(); + check_generics(class)?; if let syn::Fields::Named(ref mut fields) = class.fields { for field in fields.named.iter_mut() { let field_descs = parse_descriptors(field)?; @@ -461,3 +462,14 @@ fn impl_descriptors(cls: &syn::Type, descriptors: Vec<(syn::Field, Vec)> } } } + +fn check_generics(class: &mut syn::ItemStruct) -> syn::Result<()> { + if class.generics.params.is_empty() { + Ok(()) + } else { + Err(syn::Error::new_spanned( + &class.generics, + "#[pyclass] cannot have generic parameters", + )) + } +} diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs new file mode 100644 index 00000000..0437d5e3 --- /dev/null +++ b/tests/test_compile_error.rs @@ -0,0 +1,6 @@ +#[test] +#[cfg(testkcovstopmarker)] +fn test_compile_errors() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/reject_generics.rs"); +} diff --git a/tests/ui/reject_generics.rs b/tests/ui/reject_generics.rs new file mode 100644 index 00000000..b400cd2b --- /dev/null +++ b/tests/ui/reject_generics.rs @@ -0,0 +1,8 @@ +use pyo3::prelude::*; + +#[pyclass] +struct ClassWithGenerics { + a: A, +} + +fn main() {} diff --git a/tests/ui/reject_generics.stderr b/tests/ui/reject_generics.stderr new file mode 100644 index 00000000..c06f9dfb --- /dev/null +++ b/tests/ui/reject_generics.stderr @@ -0,0 +1,5 @@ +error: #[pyclass] cannot have generic parameters + --> $DIR/reject_generics.rs:4:25 + | +4 | struct ClassWithGenerics { + | ^^^