Skip to content

Commit 012e095

Browse files
authored
remove ptr_from_ref helpers (#5523)
1 parent f9e14fc commit 012e095

File tree

4 files changed

+26
-30
lines changed

4 files changed

+26
-30
lines changed

src/instance.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::call::PyCallArgs;
44
use crate::conversion::IntoPyObject;
55
use crate::err::{PyErr, PyResult};
66
use crate::impl_::pycell::PyClassObject;
7-
use crate::internal_tricks::ptr_from_ref;
87
use crate::pycell::{PyBorrowError, PyBorrowMutError};
98
use crate::pyclass::boolean_struct::{False, True};
109
use crate::types::{any::PyAnyMethods, string::PyStringMethods, typeobject::PyTypeMethods};
@@ -444,9 +443,10 @@ impl<'py> Bound<'py, PyAny> {
444443
_py: Python<'py>,
445444
ptr: &'a *mut ffi::PyObject,
446445
) -> &'a Self {
446+
let ptr = NonNull::from(ptr).cast();
447447
// SAFETY: caller has upheld the safety contract,
448448
// and `Bound<PyAny>` is layout-compatible with `*mut ffi::PyObject`.
449-
unsafe { &*ptr_from_ref(ptr).cast::<Bound<'py, PyAny>>() }
449+
unsafe { ptr.as_ref() }
450450
}
451451

452452
/// Variant of the above which returns `None` for null pointers.
@@ -458,9 +458,10 @@ impl<'py> Bound<'py, PyAny> {
458458
_py: Python<'py>,
459459
ptr: &'a *mut ffi::PyObject,
460460
) -> &'a Option<Self> {
461+
let ptr = NonNull::from(ptr).cast();
461462
// SAFETY: caller has upheld the safety contract,
462463
// and `Option<Bound<PyAny>>` is layout-compatible with `*mut ffi::PyObject`.
463-
unsafe { &*ptr_from_ref(ptr).cast::<Option<Bound<'py, PyAny>>>() }
464+
unsafe { ptr.as_ref() }
464465
}
465466

466467
/// This slightly strange method is used to obtain `&Bound<PyAny>` from a [`NonNull`] in macro
@@ -477,9 +478,10 @@ impl<'py> Bound<'py, PyAny> {
477478
_py: Python<'py>,
478479
ptr: &'a NonNull<ffi::PyObject>,
479480
) -> &'a Self {
481+
let ptr = NonNull::from(ptr).cast();
480482
// SAFETY: caller has upheld the safety contract,
481483
// and `Bound<PyAny>` is layout-compatible with `NonNull<ffi::PyObject>`.
482-
unsafe { NonNull::from(ptr).cast().as_ref() }
484+
unsafe { ptr.as_ref() }
483485
}
484486
}
485487

@@ -839,9 +841,10 @@ impl<'py, T> Bound<'py, T> {
839841
/// Helper to cast to `Bound<'py, PyAny>`.
840842
#[inline]
841843
pub fn as_any(&self) -> &Bound<'py, PyAny> {
844+
let ptr = NonNull::from(self).cast();
842845
// Safety: all Bound<T> have the same memory layout, and all Bound<T> are valid
843846
// Bound<PyAny>, so pointer casting is valid.
844-
unsafe { &*ptr_from_ref(self).cast::<Bound<'py, PyAny>>() }
847+
unsafe { ptr.as_ref() }
845848
}
846849

847850
/// Helper to cast to `Bound<'py, PyAny>`, transferring ownership.
@@ -1171,8 +1174,8 @@ impl<'py, T> Deref for Borrowed<'_, 'py, T> {
11711174

11721175
#[inline]
11731176
fn deref(&self) -> &Bound<'py, T> {
1174-
// safety: Bound has the same layout as NonNull<ffi::PyObject>
1175-
unsafe { &*ptr_from_ref(&self.0).cast() }
1177+
// SAFETY: self.0 is a valid object of type T
1178+
unsafe { Bound::ref_from_non_null(self.2, &self.0).cast_unchecked() }
11761179
}
11771180
}
11781181

@@ -1483,9 +1486,10 @@ impl<T> Py<T> {
14831486
/// Helper to cast to `Py<PyAny>`.
14841487
#[inline]
14851488
pub fn as_any(&self) -> &Py<PyAny> {
1489+
let ptr = NonNull::from(self).cast();
14861490
// Safety: all Py<T> have the same memory layout, and all Py<T> are valid
14871491
// Py<PyAny>, so pointer casting is valid.
1488-
unsafe { &*ptr_from_ref(self).cast::<Py<PyAny>>() }
1492+
unsafe { ptr.as_ref() }
14891493
}
14901494

14911495
/// Helper to cast to `Py<PyAny>`, transferring ownership.

src/internal_tricks.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,6 @@ pub(crate) fn get_ssize_index(index: usize) -> Py_ssize_t {
1919
index.min(PY_SSIZE_T_MAX as usize) as Py_ssize_t
2020
}
2121

22-
// TODO: use ptr::from_ref on MSRV 1.76
23-
#[inline]
24-
pub(crate) const fn ptr_from_ref<T>(t: &T) -> *const T {
25-
t as *const T
26-
}
27-
28-
// TODO: use ptr::from_mut on MSRV 1.76
29-
#[inline]
30-
pub(crate) fn ptr_from_mut<T>(t: &mut T) -> *mut T {
31-
t as *mut T
32-
}
33-
3422
// TODO: use ptr::fn_addr_eq on MSRV 1.85
3523
pub(crate) fn clear_eq(f: Option<ffi::inquiry>, g: ffi::inquiry) -> bool {
3624
#[cfg(fn_ptr_eq)]

src/pycell.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -196,13 +196,13 @@
196196
use crate::conversion::IntoPyObject;
197197
use crate::exceptions::PyRuntimeError;
198198
use crate::ffi_ptr_ext::FfiPtrExt;
199-
use crate::internal_tricks::{ptr_from_mut, ptr_from_ref};
200199
use crate::pyclass::{boolean_struct::False, PyClass};
201200
use crate::{ffi, Borrowed, Bound, PyErr, Python};
202201
use std::convert::Infallible;
203202
use std::fmt;
204203
use std::mem::ManuallyDrop;
205204
use std::ops::{Deref, DerefMut};
205+
use std::ptr::NonNull;
206206

207207
pub(crate) mod impl_;
208208
use impl_::{PyClassBorrowChecker, PyClassObjectLayout};
@@ -444,12 +444,13 @@ where
444444
/// # });
445445
/// ```
446446
pub fn as_super(&self) -> &PyRef<'p, U> {
447-
let ptr = ptr_from_ref::<Bound<'p, T>>(&self.inner)
447+
let ptr = NonNull::from(&self.inner)
448448
// `Bound<T>` has the same layout as `Bound<T::BaseType>`
449449
.cast::<Bound<'p, T::BaseType>>()
450450
// `Bound<T::BaseType>` has the same layout as `PyRef<T::BaseType>`
451451
.cast::<PyRef<'p, T::BaseType>>();
452-
unsafe { &*ptr }
452+
// SAFETY: lifetimes are correctly transferred, and `PyRef<T>` and `PyRef<U>` have the same layout
453+
unsafe { ptr.as_ref() }
453454
}
454455
}
455456

@@ -580,8 +581,9 @@ impl<'py, T: PyClass<Frozen = False>> PyRefMut<'py, T> {
580581
}
581582

582583
pub(crate) fn downgrade(slf: &Self) -> &PyRef<'py, T> {
583-
// `PyRefMut<T>` and `PyRef<T>` have the same layout
584-
unsafe { &*ptr_from_ref(slf).cast() }
584+
let ptr = NonNull::from(slf).cast();
585+
// SAFETY: `PyRefMut<T>` and `PyRef<T>` have the same layout
586+
unsafe { ptr.as_ref() }
585587
}
586588
}
587589

@@ -613,13 +615,14 @@ where
613615
///
614616
/// See [`PyRef::as_super`] for more.
615617
pub fn as_super(&mut self) -> &mut PyRefMut<'p, U> {
616-
let ptr = ptr_from_mut::<Bound<'p, T>>(&mut self.inner)
618+
let mut ptr = NonNull::from(&mut self.inner)
617619
// `Bound<T>` has the same layout as `Bound<T::BaseType>`
618620
.cast::<Bound<'p, T::BaseType>>()
619621
// `Bound<T::BaseType>` has the same layout as `PyRefMut<T::BaseType>`,
620622
// and the mutable borrow on `self` prevents aliasing
621623
.cast::<PyRefMut<'p, T::BaseType>>();
622-
unsafe { &mut *ptr }
624+
// SAFETY: lifetimes are correctly transferred, and `PyRefMut<T>` and `PyRefMut<U>` have the same layout
625+
unsafe { ptr.as_mut() }
623626
}
624627
}
625628

src/pyclass/create_type_object.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,14 @@ use crate::{
1010
pymethods::{Getter, PyGetterDef, PyMethodDefType, PySetterDef, Setter, _call_clear},
1111
trampoline::trampoline,
1212
},
13-
internal_tricks::ptr_from_ref,
1413
types::{typeobject::PyTypeMethods, PyType},
1514
Py, PyClass, PyResult, PyTypeInfo, Python,
1615
};
1716
use std::{
1817
collections::HashMap,
1918
ffi::{CStr, CString},
2019
os::raw::{c_char, c_int, c_ulong, c_void},
21-
ptr,
20+
ptr::{self, NonNull},
2221
};
2322

2423
pub(crate) struct PyClassTypeObject {
@@ -700,7 +699,9 @@ impl GetSetDefType {
700699
(
701700
Some(getset_getter),
702701
Some(getset_setter),
703-
ptr_from_ref::<GetterAndSetter>(closure) as *mut _,
702+
NonNull::<GetterAndSetter>::from(closure.as_ref())
703+
.cast()
704+
.as_ptr(),
704705
)
705706
}
706707
};

0 commit comments

Comments
 (0)