From 498689423e122804543e78de6e281bfcc5f8b239 Mon Sep 17 00:00:00 2001 From: kngwyu Date: Mon, 25 Feb 2019 23:15:13 +0900 Subject: [PATCH] Make PyNativeType unsafe --- src/instance.rs | 37 +++++++++++++++---------------------- src/type_object.rs | 7 +------ src/types/mod.rs | 6 +----- 3 files changed, 17 insertions(+), 33 deletions(-) diff --git a/src/instance.rs b/src/instance.rs index 9f949d02..66a7edb8 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -22,8 +22,10 @@ use std::rc::Rc; /// /// pyo3 is designed in a way that that all references to those types are bound to the GIL, /// which is why you can get a token from all references of those types. -pub trait PyNativeType: Sized { - fn py(&self) -> Python; +pub unsafe trait PyNativeType: Sized { + fn py(&self) -> Python { + unsafe { Python::assume_gil_acquired() } + } } /// A special reference of type `T`. `PyRef` refers a instance of T, which exists in the Python @@ -58,6 +60,13 @@ pub trait PyNativeType: Sized { #[derive(Debug)] pub struct PyRef<'a, T: PyTypeInfo>(&'a T, PhantomData>); +fn ref_to_ptr(t: &T) -> *mut ffi::PyObject +where + T: PyTypeInfo, +{ + unsafe { (t as *const _ as *mut u8).offset(-T::OFFSET) as *mut _ } +} + impl<'a, T: PyTypeInfo> PyRef<'a, T> { pub(crate) fn from_ref(r: &'a T) -> Self { PyRef(r, PhantomData) @@ -78,7 +87,7 @@ where impl<'a, T: PyTypeInfo> ToPyPointer for PyRef<'a, T> { fn as_ptr(&self) -> *mut ffi::PyObject { - self.0.as_ptr_dispatch() + ref_to_ptr(self.0) } } @@ -141,7 +150,7 @@ where impl<'a, T: PyTypeInfo> ToPyPointer for PyRefMut<'a, T> { fn as_ptr(&self) -> *mut ffi::PyObject { - (self.0 as &T).as_ptr_dispatch() + ref_to_ptr(self.0) } } @@ -182,22 +191,6 @@ where } } -/// Specialization workaround -trait PyRefDispatch { - #[allow(clippy::cast_ptr_alignment)] - fn as_ptr_dispatch(&self) -> *mut ffi::PyObject { - unsafe { (self as *const _ as *mut u8).offset(-T::OFFSET) as *mut _ } - } -} - -impl PyRefDispatch for T {} - -impl PyRefDispatch for T { - fn as_ptr_dispatch(&self) -> *mut ffi::PyObject { - self as *const _ as *mut _ - } -} - /// Trait implements object reference extraction from python managed pointer. pub trait AsPyRef: Sized { /// Return reference to object. @@ -355,13 +348,13 @@ trait AsPyRefDispatch: ToPyPointer { fn as_ref_dispatch(&self, _py: Python) -> &T { unsafe { let ptr = (self.as_ptr() as *mut u8).offset(T::OFFSET) as *mut T; - ptr.as_ref().unwrap() + ptr.as_ref().expect("Py has a null pointer") } } fn as_mut_dispatch(&mut self, _py: Python) -> &mut T { unsafe { let ptr = (self.as_ptr() as *mut u8).offset(T::OFFSET) as *mut T; - ptr.as_mut().unwrap() + ptr.as_mut().expect("Py has a null pointer") } } } diff --git a/src/type_object.rs b/src/type_object.rs index c6743fee..35e85dc3 100644 --- a/src/type_object.rs +++ b/src/type_object.rs @@ -172,12 +172,7 @@ impl IntoPyPointer for PyRawObject { } } -impl PyNativeType for PyRawObject { - #[inline] - fn py(&self) -> Python { - unsafe { Python::assume_gil_acquired() } - } -} +unsafe impl PyNativeType for PyRawObject {} pub(crate) unsafe fn pytype_drop(py: Python, obj: *mut ffi::PyObject) { if T::OFFSET != 0 { diff --git a/src/types/mod.rs b/src/types/mod.rs index 8e839251..dfd37974 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -64,11 +64,7 @@ macro_rules! pyobject_native_type_named ( } } - impl<$($type_param,)*> $crate::PyNativeType for $name { - fn py(&self) -> $crate::Python { - unsafe { $crate::Python::assume_gil_acquired() } - } - } + unsafe impl<$($type_param,)*> $crate::PyNativeType for $name {} impl<$($type_param,)*> $crate::ToPyPointer for $name { /// Gets the underlying FFI pointer, returns a borrowed pointer.