diff --git a/newsfragments/4725.fixed.md b/newsfragments/4725.fixed.md new file mode 100644 index 00000000000..9ee069c5eb4 --- /dev/null +++ b/newsfragments/4725.fixed.md @@ -0,0 +1 @@ +Fix `ambiguous_associated_items` lint error in `#[pyclass]` and `#[derive(IntoPyObject)]` macros. diff --git a/pyo3-macros-backend/src/intopyobject.rs b/pyo3-macros-backend/src/intopyobject.rs index 4a46c07418f..a60a5486cb8 100644 --- a/pyo3-macros-backend/src/intopyobject.rs +++ b/pyo3-macros-backend/src/intopyobject.rs @@ -512,7 +512,7 @@ impl<'a> Enum<'a> { IntoPyObjectImpl { types: IntoPyObjectTypes::Opaque { target: quote!(#pyo3_path::types::PyAny), - output: quote!(#pyo3_path::Bound<'py, Self::Target>), + output: quote!(#pyo3_path::Bound<'py, >::Target>), error: quote!(#pyo3_path::PyErr), }, body: quote! { @@ -617,7 +617,10 @@ pub fn build_derive_into_pyobject(tokens: &DeriveInput) -> Resu type Output = #output; type Error = #error; - fn into_pyobject(self, py: #pyo3_path::Python<#lt_param>) -> ::std::result::Result { + fn into_pyobject(self, py: #pyo3_path::Python<#lt_param>) -> ::std::result::Result< + ::Output, + ::Error, + > { #body } } diff --git a/pyo3-macros-backend/src/pyclass.rs b/pyo3-macros-backend/src/pyclass.rs index 87d02c6f878..93596611f18 100644 --- a/pyo3-macros-backend/src/pyclass.rs +++ b/pyo3-macros-backend/src/pyclass.rs @@ -1072,10 +1072,13 @@ fn impl_complex_enum( quote! { impl<'py> #pyo3_path::conversion::IntoPyObject<'py> for #cls { type Target = Self; - type Output = #pyo3_path::Bound<'py, Self::Target>; + type Output = #pyo3_path::Bound<'py, >::Target>; type Error = #pyo3_path::PyErr; - fn into_pyobject(self, py: #pyo3_path::Python<'py>) -> ::std::result::Result { + fn into_pyobject(self, py: #pyo3_path::Python<'py>) -> ::std::result::Result< + ::Output, + ::Error, + > { match self { #(#match_arms)* } @@ -2161,10 +2164,13 @@ impl<'a> PyClassImplsBuilder<'a> { impl<'py> #pyo3_path::conversion::IntoPyObject<'py> for #cls { type Target = Self; - type Output = #pyo3_path::Bound<'py, Self::Target>; + type Output = #pyo3_path::Bound<'py, >::Target>; type Error = #pyo3_path::PyErr; - fn into_pyobject(self, py: #pyo3_path::Python<'py>) -> ::std::result::Result { + fn into_pyobject(self, py: #pyo3_path::Python<'py>) -> ::std::result::Result< + ::Output, + ::Error, + > { #pyo3_path::Bound::new(py, self) } } diff --git a/tests/test_compile_error.rs b/tests/test_compile_error.rs index b6cf5065371..e4e80e90263 100644 --- a/tests/test_compile_error.rs +++ b/tests/test_compile_error.rs @@ -67,4 +67,5 @@ fn test_compile_errors() { t.compile_fail("tests/ui/duplicate_pymodule_submodule.rs"); #[cfg(all(not(Py_LIMITED_API), Py_3_11))] t.compile_fail("tests/ui/invalid_base_class.rs"); + t.pass("tests/ui/ambiguous_associated_items.rs"); } diff --git a/tests/ui/ambiguous_associated_items.rs b/tests/ui/ambiguous_associated_items.rs new file mode 100644 index 00000000000..f553ba1f33f --- /dev/null +++ b/tests/ui/ambiguous_associated_items.rs @@ -0,0 +1,25 @@ +use pyo3::prelude::*; + +#[pyclass(eq)] +#[derive(PartialEq)] +pub enum SimpleItems { + Error, + Output, + Target, +} + +#[pyclass] +pub enum ComplexItems { + Error(PyObject), + Output(PyObject), + Target(PyObject), +} + +#[derive(IntoPyObject)] +enum DeriveItems { + Error(PyObject), + Output(PyObject), + Target(PyObject), +} + +fn main() {}