Skip to content

Commit 02eb2a1

Browse files
LilyAcorndavidhewitt
authored andcommitted
Fix ambiguous associated item error (#4725)
* Add test for ambiguous associated item The `#[pyclass]` macro implements `IntoPyObject` for the annotated enum. When the enum has any of `Error`, `Output` or `Target` as members, this clashes with the associated types of `IntoPyObject`. This also happens when deriving `IntoPyObject` directly. * Fix #4723: ambiguous associated item in #[pyclass] This uses the fix described in rust-lang/rust#57644 Also apply fix to `#[derive(IntoPyObject)]`.
1 parent ab999ae commit 02eb2a1

File tree

5 files changed

+42
-6
lines changed

5 files changed

+42
-6
lines changed

newsfragments/4725.fixed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix `ambiguous_associated_items` lint error in `#[pyclass]` and `#[derive(IntoPyObject)]` macros.

pyo3-macros-backend/src/intopyobject.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ impl<'a> Enum<'a> {
512512
IntoPyObjectImpl {
513513
types: IntoPyObjectTypes::Opaque {
514514
target: quote!(#pyo3_path::types::PyAny),
515-
output: quote!(#pyo3_path::Bound<'py, Self::Target>),
515+
output: quote!(#pyo3_path::Bound<'py, <Self as #pyo3_path::conversion::IntoPyObject<'py>>::Target>),
516516
error: quote!(#pyo3_path::PyErr),
517517
},
518518
body: quote! {
@@ -617,7 +617,10 @@ pub fn build_derive_into_pyobject<const REF: bool>(tokens: &DeriveInput) -> Resu
617617
type Output = #output;
618618
type Error = #error;
619619

620-
fn into_pyobject(self, py: #pyo3_path::Python<#lt_param>) -> ::std::result::Result<Self::Output, Self::Error> {
620+
fn into_pyobject(self, py: #pyo3_path::Python<#lt_param>) -> ::std::result::Result<
621+
<Self as #pyo3_path::conversion::IntoPyObject>::Output,
622+
<Self as #pyo3_path::conversion::IntoPyObject>::Error,
623+
> {
621624
#body
622625
}
623626
}

pyo3-macros-backend/src/pyclass.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,10 +1072,13 @@ fn impl_complex_enum(
10721072
quote! {
10731073
impl<'py> #pyo3_path::conversion::IntoPyObject<'py> for #cls {
10741074
type Target = Self;
1075-
type Output = #pyo3_path::Bound<'py, Self::Target>;
1075+
type Output = #pyo3_path::Bound<'py, <Self as #pyo3_path::conversion::IntoPyObject<'py>>::Target>;
10761076
type Error = #pyo3_path::PyErr;
10771077

1078-
fn into_pyobject(self, py: #pyo3_path::Python<'py>) -> ::std::result::Result<Self::Output, Self::Error> {
1078+
fn into_pyobject(self, py: #pyo3_path::Python<'py>) -> ::std::result::Result<
1079+
<Self as #pyo3_path::conversion::IntoPyObject>::Output,
1080+
<Self as #pyo3_path::conversion::IntoPyObject>::Error,
1081+
> {
10791082
match self {
10801083
#(#match_arms)*
10811084
}
@@ -2161,10 +2164,13 @@ impl<'a> PyClassImplsBuilder<'a> {
21612164

21622165
impl<'py> #pyo3_path::conversion::IntoPyObject<'py> for #cls {
21632166
type Target = Self;
2164-
type Output = #pyo3_path::Bound<'py, Self::Target>;
2167+
type Output = #pyo3_path::Bound<'py, <Self as #pyo3_path::conversion::IntoPyObject<'py>>::Target>;
21652168
type Error = #pyo3_path::PyErr;
21662169

2167-
fn into_pyobject(self, py: #pyo3_path::Python<'py>) -> ::std::result::Result<Self::Output, Self::Error> {
2170+
fn into_pyobject(self, py: #pyo3_path::Python<'py>) -> ::std::result::Result<
2171+
<Self as #pyo3_path::conversion::IntoPyObject>::Output,
2172+
<Self as #pyo3_path::conversion::IntoPyObject>::Error,
2173+
> {
21682174
#pyo3_path::Bound::new(py, self)
21692175
}
21702176
}

tests/test_compile_error.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,5 @@ fn test_compile_errors() {
6767
t.compile_fail("tests/ui/duplicate_pymodule_submodule.rs");
6868
#[cfg(all(not(Py_LIMITED_API), Py_3_11))]
6969
t.compile_fail("tests/ui/invalid_base_class.rs");
70+
t.pass("tests/ui/ambiguous_associated_items.rs");
7071
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use pyo3::prelude::*;
2+
3+
#[pyclass(eq)]
4+
#[derive(PartialEq)]
5+
pub enum SimpleItems {
6+
Error,
7+
Output,
8+
Target,
9+
}
10+
11+
#[pyclass]
12+
pub enum ComplexItems {
13+
Error(PyObject),
14+
Output(PyObject),
15+
Target(PyObject),
16+
}
17+
18+
#[derive(IntoPyObject)]
19+
enum DeriveItems {
20+
Error(PyObject),
21+
Output(PyObject),
22+
Target(PyObject),
23+
}
24+
25+
fn main() {}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy