Skip to content

Can't generate #[pyproto] impls from a macro #1258

@1tgr

Description

@1tgr

The code generated for this example by the proc_macro causes a compiler error:

macro_rules! py_object_protocol {
    (_inner, Debug) => {
        fn __str__(&self) -> pyo3::prelude::PyResult<String> {
            Ok(format!("{:?}", self))
        }
    };

    ($ty:ty, $( $trait:ident ),*) => {
        #[pyo3::prelude::pyproto]
        impl pyo3::PyObjectProtocol for $ty {
            $(
                py_object_protocol!(_inner, $trait);
            )*
        }
    }
}

#[pyo3::prelude::pyclass]
#[derive(Debug)]
pub struct S {}

/* #[pyproto]
impl PyObjectProtocol for S {
    fn __str__(&self) -> PyResult<String> {
        Ok(format!("{:?}", self))
    }
} */

py_object_protocol!(S, Debug);

Compiler error from the example above:

error[E0053]: method `__str__` has an incompatible type for trait
 --> src/lib.rs:3:9
  |
3 |         fn __str__(&self) -> pyo3::prelude::PyResult<String> {
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found enum `std::result::Result`
  |
  = note: expected fn pointer `fn(&'p S) -> <S as pyo3::class::basic::PyObjectStrProtocol<'p>>::Result`
             found fn pointer `fn(&S) -> std::result::Result<std::string::String, pyo3::err::PyErr>`
  = note: consider constraining the associated type `<S as pyo3::class::basic::PyObjectStrProtocol<'p>>::Result` to `std::result::Result<std::string::String, pyo3::err::PyErr>` or calling a method that returns `<S as pyo3::class::basic::PyObjectStrProtocol<'p>>::Result`

Note that the equivalent code (commented out in the example) compiles fine.

This is pyo3 0.12.3, but I've seen the same error from previous versions.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions