Skip to content

Commit

Permalink
Merge pull request #615 from PyO3/fix-specialization
Browse files Browse the repository at this point in the history
Fix broken specialized implementations with Rust 1.40
  • Loading branch information
kngwyu authored Oct 7, 2019
2 parents 091284d + 33bf37d commit d602b65
Show file tree
Hide file tree
Showing 14 changed files with 826 additions and 325 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Fixed

* Make sure the right Python interpreter is used in OSX builds. [#604](https://github.com/PyO3/pyo3/pull/604)
* Patch specialization being broken by Rust 1.40 [#614](https://github.com/PyO3/pyo3/issues/614)

## [0.8.0] - 2018-09-05

Expand Down
6 changes: 3 additions & 3 deletions pyo3-derive-backend/src/pymethod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub fn gen_py_method(
return Err(syn::Error::new_spanned(
spec.args[0].ty,
"Getter function can only have one argument of type pyo3::Python!",
))
));
}
};
impl_py_getter_def(name, doc, getter, &impl_wrap_getter(cls, name, takes_py))
Expand All @@ -60,10 +60,10 @@ fn check_generic(name: &syn::Ident, sig: &syn::Signature) -> syn::Result<()> {
match param {
syn::GenericParam::Lifetime(_) => {}
syn::GenericParam::Type(_) => {
return Err(syn::Error::new_spanned(param, err_msg("type")))
return Err(syn::Error::new_spanned(param, err_msg("type")));
}
syn::GenericParam::Const(_) => {
return Err(syn::Error::new_spanned(param, err_msg("const")))
return Err(syn::Error::new_spanned(param, err_msg("const")));
}
}
}
Expand Down
127 changes: 94 additions & 33 deletions src/class/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,17 +152,21 @@ pub trait PyObjectRichcmpProtocol<'p>: PyObjectProtocol<'p> {

#[doc(hidden)]
pub trait PyObjectProtocolImpl {
fn methods() -> Vec<PyMethodDef> {
fn methods() -> Vec<PyMethodDef>;
fn tp_as_object(_type_object: &mut ffi::PyTypeObject);
fn nb_bool_fn() -> Option<ffi::inquiry>;
}

impl<T> PyObjectProtocolImpl for T {
default fn methods() -> Vec<PyMethodDef> {
Vec::new()
}
fn tp_as_object(_type_object: &mut ffi::PyTypeObject) {}
fn nb_bool_fn() -> Option<ffi::inquiry> {
default fn tp_as_object(_type_object: &mut ffi::PyTypeObject) {}
default fn nb_bool_fn() -> Option<ffi::inquiry> {
None
}
}

impl<T> PyObjectProtocolImpl for T {}

impl<'p, T> PyObjectProtocolImpl for T
where
T: PyObjectProtocol<'p>,
Expand Down Expand Up @@ -195,13 +199,18 @@ where
}

trait GetAttrProtocolImpl {
fn tp_getattro() -> Option<ffi::binaryfunc> {
fn tp_getattro() -> Option<ffi::binaryfunc>;
}

impl<'p, T> GetAttrProtocolImpl for T
where
T: PyObjectProtocol<'p>,
{
default fn tp_getattro() -> Option<ffi::binaryfunc> {
None
}
}

impl<'p, T> GetAttrProtocolImpl for T where T: PyObjectProtocol<'p> {}

impl<T> GetAttrProtocolImpl for T
where
T: for<'p> PyObjectGetAttrProtocol<'p>,
Expand Down Expand Up @@ -268,13 +277,15 @@ mod tp_setattro_impl {
}

trait SetAttr {
fn set_attr() -> Option<ffi::setattrofunc> {
fn set_attr() -> Option<ffi::setattrofunc>;
}

impl<'p, T: PyObjectProtocol<'p>> SetAttr for T {
default fn set_attr() -> Option<ffi::setattrofunc> {
None
}
}

impl<'p, T: PyObjectProtocol<'p>> SetAttr for T {}

impl<T> SetAttr for T
where
T: for<'p> PyObjectSetAttrProtocol<'p>,
Expand All @@ -285,13 +296,18 @@ mod tp_setattro_impl {
}

trait DelAttr {
fn del_attr() -> Option<ffi::setattrofunc> {
fn del_attr() -> Option<ffi::setattrofunc>;
}

impl<'p, T> DelAttr for T
where
T: PyObjectProtocol<'p>,
{
default fn del_attr() -> Option<ffi::setattrofunc> {
None
}
}

impl<'p, T> DelAttr for T where T: PyObjectProtocol<'p> {}

impl<T> DelAttr for T
where
T: for<'p> PyObjectDelAttrProtocol<'p>,
Expand All @@ -302,13 +318,18 @@ mod tp_setattro_impl {
}

trait SetDelAttr {
fn set_del_attr() -> Option<ffi::setattrofunc> {
fn set_del_attr() -> Option<ffi::setattrofunc>;
}

impl<'p, T> SetDelAttr for T
where
T: PyObjectProtocol<'p>,
{
default fn set_del_attr() -> Option<ffi::setattrofunc> {
None
}
}

impl<'p, T> SetDelAttr for T where T: PyObjectProtocol<'p> {}

impl<T> SetDelAttr for T
where
T: for<'p> PyObjectSetAttrProtocol<'p> + for<'p> PyObjectDelAttrProtocol<'p>,
Expand All @@ -326,11 +347,16 @@ mod tp_setattro_impl {
}

trait StrProtocolImpl {
fn tp_str() -> Option<ffi::unaryfunc> {
fn tp_str() -> Option<ffi::unaryfunc>;
}
impl<'p, T> StrProtocolImpl for T
where
T: PyObjectProtocol<'p>,
{
default fn tp_str() -> Option<ffi::unaryfunc> {
None
}
}
impl<'p, T> StrProtocolImpl for T where T: PyObjectProtocol<'p> {}
impl<T> StrProtocolImpl for T
where
T: for<'p> PyObjectStrProtocol<'p>,
Expand All @@ -346,11 +372,16 @@ where
}

trait ReprProtocolImpl {
fn tp_repr() -> Option<ffi::unaryfunc> {
fn tp_repr() -> Option<ffi::unaryfunc>;
}
impl<'p, T> ReprProtocolImpl for T
where
T: PyObjectProtocol<'p>,
{
default fn tp_repr() -> Option<ffi::unaryfunc> {
None
}
}
impl<'p, T> ReprProtocolImpl for T where T: PyObjectProtocol<'p> {}
impl<T> ReprProtocolImpl for T
where
T: for<'p> PyObjectReprProtocol<'p>,
Expand All @@ -367,34 +398,54 @@ where

#[doc(hidden)]
pub trait FormatProtocolImpl {
fn __format__() -> Option<PyMethodDef> {
fn __format__() -> Option<PyMethodDef>;
}
impl<'p, T> FormatProtocolImpl for T
where
T: PyObjectProtocol<'p>,
{
default fn __format__() -> Option<PyMethodDef> {
None
}
}
impl<'p, T> FormatProtocolImpl for T where T: PyObjectProtocol<'p> {}

#[doc(hidden)]
pub trait BytesProtocolImpl {
fn __bytes__() -> Option<PyMethodDef> {
fn __bytes__() -> Option<PyMethodDef>;
}
impl<'p, T> BytesProtocolImpl for T
where
T: PyObjectProtocol<'p>,
{
default fn __bytes__() -> Option<PyMethodDef> {
None
}
}
impl<'p, T> BytesProtocolImpl for T where T: PyObjectProtocol<'p> {}

#[doc(hidden)]
pub trait UnicodeProtocolImpl {
fn __unicode__() -> Option<PyMethodDef> {
fn __unicode__() -> Option<PyMethodDef>;
}
impl<'p, T> UnicodeProtocolImpl for T
where
T: PyObjectProtocol<'p>,
{
default fn __unicode__() -> Option<PyMethodDef> {
None
}
}
impl<'p, T> UnicodeProtocolImpl for T where T: PyObjectProtocol<'p> {}

trait HashProtocolImpl {
fn tp_hash() -> Option<ffi::hashfunc> {
fn tp_hash() -> Option<ffi::hashfunc>;
}
impl<'p, T> HashProtocolImpl for T
where
T: PyObjectProtocol<'p>,
{
default fn tp_hash() -> Option<ffi::hashfunc> {
None
}
}
impl<'p, T> HashProtocolImpl for T where T: PyObjectProtocol<'p> {}
impl<T> HashProtocolImpl for T
where
T: for<'p> PyObjectHashProtocol<'p>,
Expand All @@ -411,11 +462,16 @@ where
}

trait BoolProtocolImpl {
fn nb_bool() -> Option<ffi::inquiry> {
fn nb_bool() -> Option<ffi::inquiry>;
}
impl<'p, T> BoolProtocolImpl for T
where
T: PyObjectProtocol<'p>,
{
default fn nb_bool() -> Option<ffi::inquiry> {
None
}
}
impl<'p, T> BoolProtocolImpl for T where T: PyObjectProtocol<'p> {}
impl<T> BoolProtocolImpl for T
where
T: for<'p> PyObjectBoolProtocol<'p>,
Expand All @@ -432,11 +488,16 @@ where
}

trait RichcmpProtocolImpl {
fn tp_richcompare() -> Option<ffi::richcmpfunc> {
fn tp_richcompare() -> Option<ffi::richcmpfunc>;
}
impl<'p, T> RichcmpProtocolImpl for T
where
T: PyObjectProtocol<'p>,
{
default fn tp_richcompare() -> Option<ffi::richcmpfunc> {
None
}
}
impl<'p, T> RichcmpProtocolImpl for T where T: PyObjectProtocol<'p> {}
impl<T> RichcmpProtocolImpl for T
where
T: for<'p> PyObjectRichcmpProtocol<'p>,
Expand Down
19 changes: 13 additions & 6 deletions src/class/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,15 @@ pub trait PyBufferReleaseBufferProtocol<'p>: PyBufferProtocol<'p> {

#[doc(hidden)]
pub trait PyBufferProtocolImpl {
fn tp_as_buffer() -> Option<ffi::PyBufferProcs> {
fn tp_as_buffer() -> Option<ffi::PyBufferProcs>;
}

impl<T> PyBufferProtocolImpl for T {
default fn tp_as_buffer() -> Option<ffi::PyBufferProcs> {
None
}
}

impl<T> PyBufferProtocolImpl for T {}

impl<'p, T> PyBufferProtocolImpl for T
where
T: PyBufferProtocol<'p>,
Expand All @@ -64,13 +66,18 @@ where
}

trait PyBufferGetBufferProtocolImpl {
fn cb_bf_getbuffer() -> Option<ffi::getbufferproc> {
fn cb_bf_getbuffer() -> Option<ffi::getbufferproc>;
}

impl<'p, T> PyBufferGetBufferProtocolImpl for T
where
T: PyBufferProtocol<'p>,
{
default fn cb_bf_getbuffer() -> Option<ffi::getbufferproc> {
None
}
}

impl<'p, T> PyBufferGetBufferProtocolImpl for T where T: PyBufferProtocol<'p> {}

impl<T> PyBufferGetBufferProtocolImpl for T
where
T: for<'p> PyBufferGetBufferProtocol<'p>,
Expand Down
30 changes: 21 additions & 9 deletions src/class/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@ pub trait PyContextExitProtocol<'p>: PyContextProtocol<'p> {

#[doc(hidden)]
pub trait PyContextProtocolImpl {
fn methods() -> Vec<PyMethodDef> {
fn methods() -> Vec<PyMethodDef>;
}

impl<T> PyContextProtocolImpl for T {
default fn methods() -> Vec<PyMethodDef> {
Vec::new()
}
}

impl<T> PyContextProtocolImpl for T {}

impl<'p, T> PyContextProtocolImpl for T
where
T: PyContextProtocol<'p>,
Expand All @@ -75,18 +77,28 @@ where

#[doc(hidden)]
pub trait PyContextEnterProtocolImpl {
fn __enter__() -> Option<PyMethodDef> {
fn __enter__() -> Option<PyMethodDef>;
}

impl<'p, T> PyContextEnterProtocolImpl for T
where
T: PyContextProtocol<'p>,
{
default fn __enter__() -> Option<PyMethodDef> {
None
}
}

impl<'p, T> PyContextEnterProtocolImpl for T where T: PyContextProtocol<'p> {}

#[doc(hidden)]
pub trait PyContextExitProtocolImpl {
fn __exit__() -> Option<PyMethodDef> {
fn __exit__() -> Option<PyMethodDef>;
}

impl<'p, T> PyContextExitProtocolImpl for T
where
T: PyContextProtocol<'p>,
{
default fn __exit__() -> Option<PyMethodDef> {
None
}
}

impl<'p, T> PyContextExitProtocolImpl for T where T: PyContextProtocol<'p> {}
Loading

0 comments on commit d602b65

Please sign in to comment.