Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions newsfragments/5638.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix crash when compiling on Rust 1.92+ with both debug assertions and optimizations enabled.
34 changes: 17 additions & 17 deletions src/pycell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,10 +315,10 @@ impl<'py, T: PyClass> PyRef<'py, T> {
}
}

impl<'p, T, U> PyRef<'p, T>
impl<'p, T> PyRef<'p, T>
where
T: PyClass<BaseType = U>,
U: PyClass,
T: PyClass,
T::BaseType: PyClass,
{
/// Gets a `PyRef<T::BaseType>`.
///
Expand Down Expand Up @@ -365,10 +365,10 @@ where
/// # pyo3::py_run!(py, sub, "assert sub.name() == 'base1 base2 sub'")
/// # });
/// ```
pub fn into_super(self) -> PyRef<'p, U> {
pub fn into_super(self) -> PyRef<'p, T::BaseType> {
let py = self.py();
let t_not_frozen = !<T::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
let u_frozen = <U::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
let u_frozen = <<T::BaseType as PyClass>::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
if t_not_frozen && u_frozen {
// If `T` is mutable subclass of `U` differ, then it is possible that we need to
// release the borrow count now. (e.g. `U` may have a noop borrow checker so
Expand Down Expand Up @@ -445,7 +445,7 @@ where
/// # pyo3::py_run!(py, sub, "assert sub.format_name_lengths() == '9 8'")
/// # });
/// ```
pub fn as_super(&self) -> &PyRef<'p, U> {
pub fn as_super(&self) -> &PyRef<'p, T::BaseType> {
let ptr = NonNull::from(&self.inner)
// `Bound<T>` has the same layout as `Bound<T::BaseType>`
.cast::<Bound<'p, T::BaseType>>()
Expand Down Expand Up @@ -523,20 +523,20 @@ impl<'p, T: PyClass<Frozen = False>> PyRefMut<'p, T> {
}
}

impl<T, U> AsRef<U> for PyRefMut<'_, T>
impl<T> AsRef<T::BaseType> for PyRefMut<'_, T>
where
T: PyClass<BaseType = U, Frozen = False>,
U: PyClass<Frozen = False>,
T: PyClass<Frozen = False>,
T::BaseType: PyClass<Frozen = False>,
{
fn as_ref(&self) -> &T::BaseType {
PyRefMut::downgrade(self).as_super()
}
}

impl<T, U> AsMut<U> for PyRefMut<'_, T>
impl<T> AsMut<T::BaseType> for PyRefMut<'_, T>
where
T: PyClass<BaseType = U, Frozen = False>,
U: PyClass<Frozen = False>,
T: PyClass<Frozen = False>,
T::BaseType: PyClass<Frozen = False>,
{
fn as_mut(&mut self) -> &mut T::BaseType {
self.as_super()
Expand Down Expand Up @@ -589,15 +589,15 @@ impl<'py, T: PyClass<Frozen = False>> PyRefMut<'py, T> {
}
}

impl<'p, T, U> PyRefMut<'p, T>
impl<'p, T> PyRefMut<'p, T>
where
T: PyClass<BaseType = U, Frozen = False>,
U: PyClass<Frozen = False>,
T: PyClass<Frozen = False>,
T::BaseType: PyClass<Frozen = False>,
{
/// Gets a `PyRef<T::BaseType>`.
///
/// See [`PyRef::into_super`] for more.
pub fn into_super(self) -> PyRefMut<'p, U> {
pub fn into_super(self) -> PyRefMut<'p, T::BaseType> {
let py = self.py();
PyRefMut {
inner: unsafe {
Expand All @@ -616,7 +616,7 @@ where
/// can also be chained to access the super-superclass (and so on).
///
/// See [`PyRef::as_super`] for more.
pub fn as_super(&mut self) -> &mut PyRefMut<'p, U> {
pub fn as_super(&mut self) -> &mut PyRefMut<'p, T::BaseType> {
let mut ptr = NonNull::from(&mut self.inner)
// `Bound<T>` has the same layout as `Bound<T::BaseType>`
.cast::<Bound<'p, T::BaseType>>()
Expand Down
23 changes: 12 additions & 11 deletions src/pyclass/guard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,10 @@ impl<'a, T: PyClass> PyClassGuard<'a, T> {
}
}

impl<'a, T, U> PyClassGuard<'a, T>
impl<'a, T> PyClassGuard<'a, T>
where
T: PyClass<BaseType = U>,
U: PyClass,
T: PyClass,
T::BaseType: PyClass,
{
/// Borrows a shared reference to `PyClassGuard<T::BaseType>`.
///
Expand Down Expand Up @@ -191,7 +191,7 @@ where
/// # pyo3::py_run!(py, sub, "assert sub.format_name_lengths() == '9 8'")
/// # });
/// ```
pub fn as_super(&self) -> &PyClassGuard<'a, U> {
pub fn as_super(&self) -> &PyClassGuard<'a, T::BaseType> {
// SAFETY: `PyClassGuard<T>` and `PyClassGuard<U>` have the same layout
unsafe { NonNull::from(self).cast().as_ref() }
}
Expand Down Expand Up @@ -239,9 +239,10 @@ where
/// # pyo3::py_run!(py, sub, "assert sub.name() == 'base1 base2 sub'")
/// # });
/// ```
pub fn into_super(self) -> PyClassGuard<'a, U> {
pub fn into_super(self) -> PyClassGuard<'a, T::BaseType> {
let t_not_frozen = !<T::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
let u_frozen = <U::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
let u_frozen =
<<T::BaseType as PyClass>::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
if t_not_frozen && u_frozen {
// If `T` is a mutable subclass of a frozen `U` base, then it is possible that we need
// to release the borrow count now. (e.g. `U` may have a noop borrow checker so dropping
Expand Down Expand Up @@ -631,10 +632,10 @@ impl<'a, T: PyClass<Frozen = False>> PyClassGuardMut<'a, T> {
}
}

impl<'a, T, U> PyClassGuardMut<'a, T>
impl<'a, T> PyClassGuardMut<'a, T>
where
T: PyClass<BaseType = U, Frozen = False>,
U: PyClass<Frozen = False>,
T: PyClass<Frozen = False>,
T::BaseType: PyClass<Frozen = False>,
{
/// Borrows a mutable reference to `PyClassGuardMut<T::BaseType>`.
///
Expand All @@ -644,15 +645,15 @@ where
/// super-superclass (and so on).
///
/// See [`PyClassGuard::as_super`] for more.
pub fn as_super(&mut self) -> &mut PyClassGuardMut<'a, U> {
pub fn as_super(&mut self) -> &mut PyClassGuardMut<'a, T::BaseType> {
// SAFETY: `PyClassGuardMut<T>` and `PyClassGuardMut<U>` have the same layout
unsafe { NonNull::from(self).cast().as_mut() }
}

/// Gets a `PyClassGuardMut<T::BaseType>`.
///
/// See [`PyClassGuard::into_super`] for more.
pub fn into_super(self) -> PyClassGuardMut<'a, U> {
pub fn into_super(self) -> PyClassGuardMut<'a, T::BaseType> {
// `PyClassGuardMut` is only available for non-frozen classes, so there
// is no possibility of leaking borrows like `PyClassGuard`
PyClassGuardMut {
Expand Down
2 changes: 1 addition & 1 deletion src/pyclass_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ impl<T: PyClass> PyClassInitializer<T> {
#[inline]
pub fn add_subclass<S>(self, subclass_value: S) -> PyClassInitializer<S>
where
T: PyClassBaseType<Initializer = Self>,
S: PyClass<BaseType = T>,
S::BaseType: PyClassBaseType<Initializer = Self>,
{
PyClassInitializer::new(subclass_value, self)
}
Expand Down
Loading