From 707e4735184ce145f7bfe2a83c47626b36444ca8 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 | 5 +++++ tests/ui/reject_generics.rs | 8 ++++++++ tests/ui/reject_generics.stderr | 5 +++++ 5 files changed, 31 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 8330905de78..fbdf69b7ceb 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 04f378682a1..cbd4fbfc4ef 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 00000000000..4ef285d82df --- /dev/null +++ b/tests/test_compile_error.rs @@ -0,0 +1,5 @@ +#[test] +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 00000000000..b400cd2b7f2 --- /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 00000000000..c06f9dfb891 --- /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 { + | ^^^