Skip to content

Commit 4a0ff32

Browse files
committed
Avoid introducing generic parameter with implied bounds from an associated type relation (#5638)
* avoid introducing generic parameter with implied bounds from an associated type relation * newsfragment
1 parent eca178b commit 4a0ff32

File tree

4 files changed

+31
-29
lines changed

4 files changed

+31
-29
lines changed

newsfragments/5638.fixed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix crash when compiling on Rust 1.92+ with both debug assertions and optimizations enabled.

src/pycell.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -313,10 +313,10 @@ impl<'py, T: PyClass> PyRef<'py, T> {
313313
}
314314
}
315315

316-
impl<'p, T, U> PyRef<'p, T>
316+
impl<'p, T> PyRef<'p, T>
317317
where
318-
T: PyClass<BaseType = U>,
319-
U: PyClass,
318+
T: PyClass,
319+
T::BaseType: PyClass,
320320
{
321321
/// Gets a `PyRef<T::BaseType>`.
322322
///
@@ -363,10 +363,10 @@ where
363363
/// # pyo3::py_run!(py, sub, "assert sub.name() == 'base1 base2 sub'")
364364
/// # });
365365
/// ```
366-
pub fn into_super(self) -> PyRef<'p, U> {
366+
pub fn into_super(self) -> PyRef<'p, T::BaseType> {
367367
let py = self.py();
368368
let t_not_frozen = !<T::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
369-
let u_frozen = <U::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
369+
let u_frozen = <<T::BaseType as PyClass>::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
370370
if t_not_frozen && u_frozen {
371371
// If `T` is mutable subclass of `U` differ, then it is possible that we need to
372372
// release the borrow count now. (e.g. `U` may have a noop borrow checker so
@@ -443,7 +443,7 @@ where
443443
/// # pyo3::py_run!(py, sub, "assert sub.format_name_lengths() == '9 8'")
444444
/// # });
445445
/// ```
446-
pub fn as_super(&self) -> &PyRef<'p, U> {
446+
pub fn as_super(&self) -> &PyRef<'p, T::BaseType> {
447447
let ptr = NonNull::from(&self.inner)
448448
// `Bound<T>` has the same layout as `Bound<T::BaseType>`
449449
.cast::<Bound<'p, T::BaseType>>()
@@ -521,20 +521,20 @@ impl<'p, T: PyClass<Frozen = False>> PyRefMut<'p, T> {
521521
}
522522
}
523523

524-
impl<T, U> AsRef<U> for PyRefMut<'_, T>
524+
impl<T> AsRef<T::BaseType> for PyRefMut<'_, T>
525525
where
526-
T: PyClass<BaseType = U, Frozen = False>,
527-
U: PyClass<Frozen = False>,
526+
T: PyClass<Frozen = False>,
527+
T::BaseType: PyClass<Frozen = False>,
528528
{
529529
fn as_ref(&self) -> &T::BaseType {
530530
PyRefMut::downgrade(self).as_super()
531531
}
532532
}
533533

534-
impl<T, U> AsMut<U> for PyRefMut<'_, T>
534+
impl<T> AsMut<T::BaseType> for PyRefMut<'_, T>
535535
where
536-
T: PyClass<BaseType = U, Frozen = False>,
537-
U: PyClass<Frozen = False>,
536+
T: PyClass<Frozen = False>,
537+
T::BaseType: PyClass<Frozen = False>,
538538
{
539539
fn as_mut(&mut self) -> &mut T::BaseType {
540540
self.as_super()
@@ -587,15 +587,15 @@ impl<'py, T: PyClass<Frozen = False>> PyRefMut<'py, T> {
587587
}
588588
}
589589

590-
impl<'p, T, U> PyRefMut<'p, T>
590+
impl<'p, T> PyRefMut<'p, T>
591591
where
592-
T: PyClass<BaseType = U, Frozen = False>,
593-
U: PyClass<Frozen = False>,
592+
T: PyClass<Frozen = False>,
593+
T::BaseType: PyClass<Frozen = False>,
594594
{
595595
/// Gets a `PyRef<T::BaseType>`.
596596
///
597597
/// See [`PyRef::into_super`] for more.
598-
pub fn into_super(self) -> PyRefMut<'p, U> {
598+
pub fn into_super(self) -> PyRefMut<'p, T::BaseType> {
599599
let py = self.py();
600600
PyRefMut {
601601
inner: unsafe {
@@ -614,7 +614,7 @@ where
614614
/// can also be chained to access the super-superclass (and so on).
615615
///
616616
/// See [`PyRef::as_super`] for more.
617-
pub fn as_super(&mut self) -> &mut PyRefMut<'p, U> {
617+
pub fn as_super(&mut self) -> &mut PyRefMut<'p, T::BaseType> {
618618
let mut ptr = NonNull::from(&mut self.inner)
619619
// `Bound<T>` has the same layout as `Bound<T::BaseType>`
620620
.cast::<Bound<'p, T::BaseType>>()

src/pyclass/guard.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,10 @@ impl<'a, T: PyClass> PyClassGuard<'a, T> {
140140
}
141141
}
142142

143-
impl<'a, T, U> PyClassGuard<'a, T>
143+
impl<'a, T> PyClassGuard<'a, T>
144144
where
145-
T: PyClass<BaseType = U>,
146-
U: PyClass,
145+
T: PyClass,
146+
T::BaseType: PyClass,
147147
{
148148
/// Borrows a shared reference to `PyClassGuard<T::BaseType>`.
149149
///
@@ -189,7 +189,7 @@ where
189189
/// # pyo3::py_run!(py, sub, "assert sub.format_name_lengths() == '9 8'")
190190
/// # });
191191
/// ```
192-
pub fn as_super(&self) -> &PyClassGuard<'a, U> {
192+
pub fn as_super(&self) -> &PyClassGuard<'a, T::BaseType> {
193193
// SAFETY: `PyClassGuard<T>` and `PyClassGuard<U>` have the same layout
194194
unsafe { NonNull::from(self).cast().as_ref() }
195195
}
@@ -237,9 +237,10 @@ where
237237
/// # pyo3::py_run!(py, sub, "assert sub.name() == 'base1 base2 sub'")
238238
/// # });
239239
/// ```
240-
pub fn into_super(self) -> PyClassGuard<'a, U> {
240+
pub fn into_super(self) -> PyClassGuard<'a, T::BaseType> {
241241
let t_not_frozen = !<T::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
242-
let u_frozen = <U::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
242+
let u_frozen =
243+
<<T::BaseType as PyClass>::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
243244
if t_not_frozen && u_frozen {
244245
// If `T` is a mutable subclass of a frozen `U` base, then it is possible that we need
245246
// to release the borrow count now. (e.g. `U` may have a noop borrow checker so dropping
@@ -630,10 +631,10 @@ impl<'a, T: PyClass<Frozen = False>> PyClassGuardMut<'a, T> {
630631
}
631632
}
632633

633-
impl<'a, T, U> PyClassGuardMut<'a, T>
634+
impl<'a, T> PyClassGuardMut<'a, T>
634635
where
635-
T: PyClass<BaseType = U, Frozen = False>,
636-
U: PyClass<Frozen = False>,
636+
T: PyClass<Frozen = False>,
637+
T::BaseType: PyClass<Frozen = False>,
637638
{
638639
/// Borrows a mutable reference to `PyClassGuardMut<T::BaseType>`.
639640
///
@@ -643,15 +644,15 @@ where
643644
/// super-superclass (and so on).
644645
///
645646
/// See [`PyClassGuard::as_super`] for more.
646-
pub fn as_super(&mut self) -> &mut PyClassGuardMut<'a, U> {
647+
pub fn as_super(&mut self) -> &mut PyClassGuardMut<'a, T::BaseType> {
647648
// SAFETY: `PyClassGuardMut<T>` and `PyClassGuardMut<U>` have the same layout
648649
unsafe { NonNull::from(self).cast().as_mut() }
649650
}
650651

651652
/// Gets a `PyClassGuardMut<T::BaseType>`.
652653
///
653654
/// See [`PyClassGuard::into_super`] for more.
654-
pub fn into_super(self) -> PyClassGuardMut<'a, U> {
655+
pub fn into_super(self) -> PyClassGuardMut<'a, T::BaseType> {
655656
// `PyClassGuardMut` is only available for non-frozen classes, so there
656657
// is no possibility of leaking borrows like `PyClassGuard`
657658
PyClassGuardMut {

src/pyclass_init.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,8 @@ impl<T: PyClass> PyClassInitializer<T> {
138138
#[inline]
139139
pub fn add_subclass<S>(self, subclass_value: S) -> PyClassInitializer<S>
140140
where
141+
T: PyClassBaseType<Initializer = Self>,
141142
S: PyClass<BaseType = T>,
142-
S::BaseType: PyClassBaseType<Initializer = Self>,
143143
{
144144
PyClassInitializer::new(subclass_value, self)
145145
}

0 commit comments

Comments
 (0)