Skip to content

Commit a5a6538

Browse files
authored
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 09f961a commit a5a6538

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
@@ -315,10 +315,10 @@ impl<'py, T: PyClass> PyRef<'py, T> {
315315
}
316316
}
317317

318-
impl<'p, T, U> PyRef<'p, T>
318+
impl<'p, T> PyRef<'p, T>
319319
where
320-
T: PyClass<BaseType = U>,
321-
U: PyClass,
320+
T: PyClass,
321+
T::BaseType: PyClass,
322322
{
323323
/// Gets a `PyRef<T::BaseType>`.
324324
///
@@ -365,10 +365,10 @@ where
365365
/// # pyo3::py_run!(py, sub, "assert sub.name() == 'base1 base2 sub'")
366366
/// # });
367367
/// ```
368-
pub fn into_super(self) -> PyRef<'p, U> {
368+
pub fn into_super(self) -> PyRef<'p, T::BaseType> {
369369
let py = self.py();
370370
let t_not_frozen = !<T::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
371-
let u_frozen = <U::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
371+
let u_frozen = <<T::BaseType as PyClass>::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
372372
if t_not_frozen && u_frozen {
373373
// If `T` is mutable subclass of `U` differ, then it is possible that we need to
374374
// release the borrow count now. (e.g. `U` may have a noop borrow checker so
@@ -445,7 +445,7 @@ where
445445
/// # pyo3::py_run!(py, sub, "assert sub.format_name_lengths() == '9 8'")
446446
/// # });
447447
/// ```
448-
pub fn as_super(&self) -> &PyRef<'p, U> {
448+
pub fn as_super(&self) -> &PyRef<'p, T::BaseType> {
449449
let ptr = NonNull::from(&self.inner)
450450
// `Bound<T>` has the same layout as `Bound<T::BaseType>`
451451
.cast::<Bound<'p, T::BaseType>>()
@@ -523,20 +523,20 @@ impl<'p, T: PyClass<Frozen = False>> PyRefMut<'p, T> {
523523
}
524524
}
525525

526-
impl<T, U> AsRef<U> for PyRefMut<'_, T>
526+
impl<T> AsRef<T::BaseType> for PyRefMut<'_, T>
527527
where
528-
T: PyClass<BaseType = U, Frozen = False>,
529-
U: PyClass<Frozen = False>,
528+
T: PyClass<Frozen = False>,
529+
T::BaseType: PyClass<Frozen = False>,
530530
{
531531
fn as_ref(&self) -> &T::BaseType {
532532
PyRefMut::downgrade(self).as_super()
533533
}
534534
}
535535

536-
impl<T, U> AsMut<U> for PyRefMut<'_, T>
536+
impl<T> AsMut<T::BaseType> for PyRefMut<'_, T>
537537
where
538-
T: PyClass<BaseType = U, Frozen = False>,
539-
U: PyClass<Frozen = False>,
538+
T: PyClass<Frozen = False>,
539+
T::BaseType: PyClass<Frozen = False>,
540540
{
541541
fn as_mut(&mut self) -> &mut T::BaseType {
542542
self.as_super()
@@ -589,15 +589,15 @@ impl<'py, T: PyClass<Frozen = False>> PyRefMut<'py, T> {
589589
}
590590
}
591591

592-
impl<'p, T, U> PyRefMut<'p, T>
592+
impl<'p, T> PyRefMut<'p, T>
593593
where
594-
T: PyClass<BaseType = U, Frozen = False>,
595-
U: PyClass<Frozen = False>,
594+
T: PyClass<Frozen = False>,
595+
T::BaseType: PyClass<Frozen = False>,
596596
{
597597
/// Gets a `PyRef<T::BaseType>`.
598598
///
599599
/// See [`PyRef::into_super`] for more.
600-
pub fn into_super(self) -> PyRefMut<'p, U> {
600+
pub fn into_super(self) -> PyRefMut<'p, T::BaseType> {
601601
let py = self.py();
602602
PyRefMut {
603603
inner: unsafe {
@@ -616,7 +616,7 @@ where
616616
/// can also be chained to access the super-superclass (and so on).
617617
///
618618
/// See [`PyRef::as_super`] for more.
619-
pub fn as_super(&mut self) -> &mut PyRefMut<'p, U> {
619+
pub fn as_super(&mut self) -> &mut PyRefMut<'p, T::BaseType> {
620620
let mut ptr = NonNull::from(&mut self.inner)
621621
// `Bound<T>` has the same layout as `Bound<T::BaseType>`
622622
.cast::<Bound<'p, T::BaseType>>()

src/pyclass/guard.rs

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

145-
impl<'a, T, U> PyClassGuard<'a, T>
145+
impl<'a, T> PyClassGuard<'a, T>
146146
where
147-
T: PyClass<BaseType = U>,
148-
U: PyClass,
147+
T: PyClass,
148+
T::BaseType: PyClass,
149149
{
150150
/// Borrows a shared reference to `PyClassGuard<T::BaseType>`.
151151
///
@@ -191,7 +191,7 @@ where
191191
/// # pyo3::py_run!(py, sub, "assert sub.format_name_lengths() == '9 8'")
192192
/// # });
193193
/// ```
194-
pub fn as_super(&self) -> &PyClassGuard<'a, U> {
194+
pub fn as_super(&self) -> &PyClassGuard<'a, T::BaseType> {
195195
// SAFETY: `PyClassGuard<T>` and `PyClassGuard<U>` have the same layout
196196
unsafe { NonNull::from(self).cast().as_ref() }
197197
}
@@ -239,9 +239,10 @@ where
239239
/// # pyo3::py_run!(py, sub, "assert sub.name() == 'base1 base2 sub'")
240240
/// # });
241241
/// ```
242-
pub fn into_super(self) -> PyClassGuard<'a, U> {
242+
pub fn into_super(self) -> PyClassGuard<'a, T::BaseType> {
243243
let t_not_frozen = !<T::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
244-
let u_frozen = <U::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
244+
let u_frozen =
245+
<<T::BaseType as PyClass>::Frozen as crate::pyclass::boolean_struct::private::Boolean>::VALUE;
245246
if t_not_frozen && u_frozen {
246247
// If `T` is a mutable subclass of a frozen `U` base, then it is possible that we need
247248
// to release the borrow count now. (e.g. `U` may have a noop borrow checker so dropping
@@ -631,10 +632,10 @@ impl<'a, T: PyClass<Frozen = False>> PyClassGuardMut<'a, T> {
631632
}
632633
}
633634

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

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