changeset 52851:d9d6ae9b9722

rust-pyo3-dirstate: making bytes slices in core Sync For the purposes of providing PyO3 bindings, the data fields that will be exposed to Python have to be `Sync`, hence that is the case of `OwningDirstateMap` and its `owner` field. We had to do something similar for the PyO3 bindings of `revlog`. In this case, it forces us to adapt the `Deref` wrapper of `PyBytes` used in `hg-cpython`, because it must itself now be `Sync` and raw pointers are not. This looks even uglier than it used to, but it does not matter much, because our ultimate goal is to remove the rust-cpython bindings altogether.
author Georges Racinet <georges.racinet@cloudcrane.io>
date Wed, 29 Jan 2025 12:37:06 +0100
parents ffda57aa98fa
children 6b3b69b32a41
files rust/hg-core/src/dirstate/owning.rs rust/hg-cpython/src/pybytes_deref.rs
diffstat 2 files changed, 10 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/rust/hg-core/src/dirstate/owning.rs	Fri Jan 24 16:05:16 2025 +0100
+++ b/rust/hg-core/src/dirstate/owning.rs	Wed Jan 29 12:37:06 2025 +0100
@@ -11,7 +11,7 @@
     /// Keep a `DirstateMap<'owner>` next to the `owner` buffer that it
     /// borrows.
     pub struct OwningDirstateMap {
-        owner: Box<dyn Deref<Target = [u8]> + Send>,
+        owner: Box<dyn Deref<Target = [u8]> + Send + Sync>,
         #[covariant]
         dependent: DirstateMap,
     }
@@ -23,7 +23,7 @@
         identity: Option<DirstateIdentity>,
     ) -> Self
     where
-        OnDisk: Deref<Target = [u8]> + Send + 'static,
+        OnDisk: Deref<Target = [u8]> + Send + Sync + 'static,
     {
         let on_disk = Box::new(on_disk);
 
@@ -39,7 +39,7 @@
         identity: Option<DirstateIdentity>,
     ) -> Result<(Self, DirstateParents), DirstateError>
     where
-        OnDisk: Deref<Target = [u8]> + Send + 'static,
+        OnDisk: Deref<Target = [u8]> + Send + Sync + 'static,
     {
         let on_disk = Box::new(on_disk);
         let mut parents = DirstateParents::NULL;
@@ -63,7 +63,7 @@
         identity: Option<DirstateIdentity>,
     ) -> Result<Self, DirstateError>
     where
-        OnDisk: Deref<Target = [u8]> + Send + 'static,
+        OnDisk: Deref<Target = [u8]> + Send + Sync + 'static,
     {
         let on_disk = Box::new(on_disk);
 
--- a/rust/hg-cpython/src/pybytes_deref.rs	Fri Jan 24 16:05:16 2025 +0100
+++ b/rust/hg-cpython/src/pybytes_deref.rs	Wed Jan 29 12:37:06 2025 +0100
@@ -18,13 +18,16 @@
 
     /// Borrows the buffer inside `self.keep_alive`,
     /// but the borrow-checker cannot express self-referential structs.
-    data: *const [u8],
+    data: &'static [u8],
 }
 
 impl PyBytesDeref {
     pub fn new(py: Python, bytes: PyBytes) -> Self {
+        let as_raw: *const [u8] = bytes.data(py);
         Self {
-            data: bytes.data(py),
+            // Safety: the raw pointer is valid as long as the PyBytes is still
+            // alive, and the objecs owns it.
+            data: unsafe { &*as_raw },
             keep_alive: bytes,
         }
     }
@@ -38,9 +41,7 @@
     type Target = [u8];
 
     fn deref(&self) -> &[u8] {
-        // Safety: the raw pointer is valid as long as the PyBytes is still
-        // alive, and the returned slice borrows `self`.
-        unsafe { &*self.data }
+        self.data
     }
 }