summaryrefslogtreecommitdiff
path: root/compiler/rustc_data_structures/src/owned_slice.rs
diff options
context:
space:
mode:
authorMaybe Waffle <waffle.lapkin@gmail.com>2023-04-10 14:33:33 +0000
committerMaybe Waffle <waffle.lapkin@gmail.com>2023-05-16 11:43:27 +0000
commit086c08d86ac4d63f12961e37ef433a6128ad974b (patch)
treeb113f8171533486311ce8b154204c54f84b48e5d /compiler/rustc_data_structures/src/owned_slice.rs
parent2eef27a6c1808377e84d68c474f8246a2dafda63 (diff)
downloadrust-086c08d86ac4d63f12961e37ef433a6128ad974b.tar.gz
Switch `OwnedSlice` to use `Lrc` & remove `Lrc` from `MetadataBlob`
Diffstat (limited to 'compiler/rustc_data_structures/src/owned_slice.rs')
-rw-r--r--compiler/rustc_data_structures/src/owned_slice.rs35
1 files changed, 32 insertions, 3 deletions
diff --git a/compiler/rustc_data_structures/src/owned_slice.rs b/compiler/rustc_data_structures/src/owned_slice.rs
index 311a42aa42a..8cf74a98adb 100644
--- a/compiler/rustc_data_structures/src/owned_slice.rs
+++ b/compiler/rustc_data_structures/src/owned_slice.rs
@@ -1,5 +1,6 @@
use std::{borrow::Borrow, ops::Deref};
+use crate::sync::Lrc;
// Use our fake Send/Sync traits when on not parallel compiler,
// so that `OwnedSlice` only implements/requires Send/Sync
// for parallel compiler builds.
@@ -7,7 +8,7 @@ use crate::sync::{Send, Sync};
/// An owned slice.
///
-/// This is similar to `Box<[u8]>` but allows slicing and using anything as the
+/// This is similar to `Lrc<[u8]>` but allows slicing and using anything as the
/// backing buffer.
///
/// See [`slice_owned`] for `OwnedSlice` construction and examples.
@@ -16,6 +17,7 @@ use crate::sync::{Send, Sync};
///
/// This is essentially a replacement for `owning_ref` which is a lot simpler
/// and even sound! 🌸
+#[derive(Clone)]
pub struct OwnedSlice {
/// This is conceptually a `&'self.owner [u8]`.
bytes: *const [u8],
@@ -31,7 +33,7 @@ pub struct OwnedSlice {
// \/
// ⊂(´・◡・⊂ )∘˚˳° (I am the phantom remnant of #97770)
#[expect(dead_code)]
- owner: Box<dyn Send + Sync>,
+ owner: Lrc<dyn Send + Sync>,
}
/// Makes an [`OwnedSlice`] out of an `owner` and a `slicer` function.
@@ -83,12 +85,39 @@ where
// N.B. the HRTB on the `slicer` is important — without it the caller could provide
// a short lived slice, unrelated to the owner.
- let owner = Box::new(owner);
+ let owner = Lrc::new(owner);
let bytes = slicer(&*owner)?;
Ok(OwnedSlice { bytes, owner })
}
+impl OwnedSlice {
+ /// Slice this slice by `slicer`.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use rustc_data_structures::owned_slice::{OwnedSlice, slice_owned};
+ /// let vec = vec![1, 2, 3, 4];
+ ///
+ /// // Identical to slicing via `&v[1..3]` but produces an owned slice
+ /// let slice: OwnedSlice = slice_owned(vec, |v| &v[..]);
+ /// assert_eq!(&*slice, [1, 2, 3, 4]);
+ ///
+ /// let slice = slice.slice(|slice| &slice[1..][..2]);
+ /// assert_eq!(&*slice, [2, 3]);
+ /// ```
+ ///
+ pub fn slice(self, slicer: impl FnOnce(&[u8]) -> &[u8]) -> OwnedSlice {
+ // This is basically identical to `try_slice_owned`,
+ // `slicer` can only return slices of its argument or some static data,
+ // both of which are valid while `owner` is alive.
+
+ let bytes = slicer(&self);
+ OwnedSlice { bytes, ..self }
+ }
+}
+
impl Deref for OwnedSlice {
type Target = [u8];