| 1 | /// Helper function that can be used at compile time to emit a diagnostic if |
| 2 | /// the type does not implement `Sync` when it should. |
| 3 | /// |
| 4 | /// The mere act of invoking this function will cause the diagnostic to be |
| 5 | /// emitted if `T` does not implement `Sync` when it should. |
| 6 | /// |
| 7 | /// The additional `const IS_SYNC: bool` parameter is used to allow the custom |
| 8 | /// diagnostic to be emitted; if `PyClassSync` |
| 9 | #[allow (unused)] |
| 10 | pub const fn assert_pyclass_sync<T>() |
| 11 | where |
| 12 | T: PyClassSync + Sync, |
| 13 | { |
| 14 | } |
| 15 | |
| 16 | #[cfg_attr ( |
| 17 | diagnostic_namespace, |
| 18 | diagnostic::on_unimplemented( |
| 19 | message = "the trait `Sync` is not implemented for `{Self}`" , |
| 20 | label = "required by `#[pyclass]`" , |
| 21 | note = "replace thread-unsafe fields with thread-safe alternatives" , |
| 22 | note = "see <TODO INSERT PYO3 GUIDE> for more information" , |
| 23 | ) |
| 24 | )] |
| 25 | pub trait PyClassSync<T: Sync = Self> {} |
| 26 | |
| 27 | impl<T> PyClassSync for T where T: Sync {} |
| 28 | |
| 29 | mod tests { |
| 30 | #[cfg (feature = "macros" )] |
| 31 | #[test ] |
| 32 | fn test_assert_pyclass_sync() { |
| 33 | use super::assert_pyclass_sync; |
| 34 | |
| 35 | #[crate::pyclass (crate = "crate" )] |
| 36 | struct MyClass {} |
| 37 | |
| 38 | assert_pyclass_sync::<MyClass>(); |
| 39 | } |
| 40 | } |
| 41 | |