Mercurial > public > mercurial-scm > hg
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 } }