Skip to content

Commit 086c08d

Browse files
committed
Switch OwnedSlice to use Lrc & remove Lrc from MetadataBlob
1 parent 2eef27a commit 086c08d

File tree

6 files changed

+47
-13
lines changed

6 files changed

+47
-13
lines changed

compiler/rustc_data_structures/src/owned_slice.rs

+32-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
use std::{borrow::Borrow, ops::Deref};
22

3+
use crate::sync::Lrc;
34
// Use our fake Send/Sync traits when on not parallel compiler,
45
// so that `OwnedSlice` only implements/requires Send/Sync
56
// for parallel compiler builds.
67
use crate::sync::{Send, Sync};
78

89
/// An owned slice.
910
///
10-
/// This is similar to `Box<[u8]>` but allows slicing and using anything as the
11+
/// This is similar to `Lrc<[u8]>` but allows slicing and using anything as the
1112
/// backing buffer.
1213
///
1314
/// See [`slice_owned`] for `OwnedSlice` construction and examples.
@@ -16,6 +17,7 @@ use crate::sync::{Send, Sync};
1617
///
1718
/// This is essentially a replacement for `owning_ref` which is a lot simpler
1819
/// and even sound! 🌸
20+
#[derive(Clone)]
1921
pub struct OwnedSlice {
2022
/// This is conceptually a `&'self.owner [u8]`.
2123
bytes: *const [u8],
@@ -31,7 +33,7 @@ pub struct OwnedSlice {
3133
// \/
3234
// ⊂(´・◡・⊂ )∘˚˳° (I am the phantom remnant of #97770)
3335
#[expect(dead_code)]
34-
owner: Box<dyn Send + Sync>,
36+
owner: Lrc<dyn Send + Sync>,
3537
}
3638

3739
/// Makes an [`OwnedSlice`] out of an `owner` and a `slicer` function.
@@ -83,12 +85,39 @@ where
8385
// N.B. the HRTB on the `slicer` is important — without it the caller could provide
8486
// a short lived slice, unrelated to the owner.
8587

86-
let owner = Box::new(owner);
88+
let owner = Lrc::new(owner);
8789
let bytes = slicer(&*owner)?;
8890

8991
Ok(OwnedSlice { bytes, owner })
9092
}
9193

94+
impl OwnedSlice {
95+
/// Slice this slice by `slicer`.
96+
///
97+
/// # Examples
98+
///
99+
/// ```rust
100+
/// # use rustc_data_structures::owned_slice::{OwnedSlice, slice_owned};
101+
/// let vec = vec![1, 2, 3, 4];
102+
///
103+
/// // Identical to slicing via `&v[1..3]` but produces an owned slice
104+
/// let slice: OwnedSlice = slice_owned(vec, |v| &v[..]);
105+
/// assert_eq!(&*slice, [1, 2, 3, 4]);
106+
///
107+
/// let slice = slice.slice(|slice| &slice[1..][..2]);
108+
/// assert_eq!(&*slice, [2, 3]);
109+
/// ```
110+
///
111+
pub fn slice(self, slicer: impl FnOnce(&[u8]) -> &[u8]) -> OwnedSlice {
112+
// This is basically identical to `try_slice_owned`,
113+
// `slicer` can only return slices of its argument or some static data,
114+
// both of which are valid while `owner` is alive.
115+
116+
let bytes = slicer(&self);
117+
OwnedSlice { bytes, ..self }
118+
}
119+
}
120+
92121
impl Deref for OwnedSlice {
93122
type Target = [u8];
94123

compiler/rustc_data_structures/src/owned_slice/tests.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fn static_storage() {
2626
}
2727

2828
#[test]
29-
fn slice_the_slice() {
29+
fn slice_owned_the_slice() {
3030
let slice = slice_owned(vec![1, 2, 3, 4, 5, 6], Vec::as_slice);
3131
let slice = slice_owned(slice, |s| &s[1..][..4]);
3232
let slice = slice_owned(slice, |s| s);
@@ -35,6 +35,16 @@ fn slice_the_slice() {
3535
assert_eq!(&*slice, &[1, 2, 3, 4, 5, 6][1..][..4][1..]);
3636
}
3737

38+
#[test]
39+
fn slice_the_slice() {
40+
let slice = slice_owned(vec![1, 2, 3, 4, 5, 6], Vec::as_slice)
41+
.slice(|s| &s[1..][..4])
42+
.slice(|s| s)
43+
.slice(|s| &s[1..]);
44+
45+
assert_eq!(&*slice, &[1, 2, 3, 4, 5, 6][1..][..4][1..]);
46+
}
47+
3848
#[test]
3949
fn try_and_fail() {
4050
let res = try_slice_owned(vec![0], |v| v.get(12..).ok_or(()));

compiler/rustc_metadata/src/locator.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ fn get_metadata_section<'p>(
843843
slice_owned(mmap, Deref::deref)
844844
}
845845
};
846-
let blob = MetadataBlob::new(raw_bytes);
846+
let blob = MetadataBlob(raw_bytes);
847847
if blob.is_compatible() {
848848
Ok(blob)
849849
} else {

compiler/rustc_metadata/src/rmeta/decoder.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::rmeta::*;
77
use rustc_ast as ast;
88
use rustc_data_structures::captures::Captures;
99
use rustc_data_structures::fx::FxHashMap;
10+
use rustc_data_structures::owned_slice::OwnedSlice;
1011
use rustc_data_structures::svh::Svh;
1112
use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc, OnceCell};
1213
use rustc_data_structures::unhash::UnhashMap;
@@ -50,7 +51,7 @@ mod cstore_impl;
5051
/// A `MetadataBlob` internally is just a reference counted pointer to
5152
/// the actual data, so cloning it is cheap.
5253
#[derive(Clone)]
53-
pub(crate) struct MetadataBlob(Lrc<MetadataRef>);
54+
pub(crate) struct MetadataBlob(pub(crate) OwnedSlice);
5455

5556
impl std::ops::Deref for MetadataBlob {
5657
type Target = [u8];
@@ -660,10 +661,6 @@ impl<'a, 'tcx, I: Idx, T> Decodable<DecodeContext<'a, 'tcx>> for LazyTable<I, T>
660661
implement_ty_decoder!(DecodeContext<'a, 'tcx>);
661662

662663
impl MetadataBlob {
663-
pub(crate) fn new(metadata_ref: MetadataRef) -> MetadataBlob {
664-
MetadataBlob(Lrc::new(metadata_ref))
665-
}
666-
667664
pub(crate) fn is_compatible(&self) -> bool {
668665
self.blob().starts_with(METADATA_HEADER)
669666
}

compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::rmeta::DecodeContext;
22
use crate::rmeta::EncodeContext;
3-
use rustc_data_structures::owned_slice::slice_owned;
43
use rustc_data_structures::owned_slice::OwnedSlice;
54
use rustc_hir::def_path_hash_map::{Config as HashMapConfig, DefPathHashMap};
65
use rustc_middle::parameterized_over_tcx;
@@ -47,7 +46,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for DefPathHashMapRef<'static>
4746
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> DefPathHashMapRef<'static> {
4847
let len = d.read_usize();
4948
let pos = d.position();
50-
let o = slice_owned(d.blob().clone(), |blob| &blob[pos..pos + len]);
49+
let o = d.blob().clone().0.slice(|blob| &blob[pos..pos + len]);
5150

5251
// Although we already have the data we need via the `OwnedSlice`, we still need
5352
// to advance the `DecodeContext`'s position so it's in a valid state after

compiler/rustc_metadata/src/rmeta/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use table::TableBuilder;
77
use rustc_ast as ast;
88
use rustc_attr as attr;
99
use rustc_data_structures::svh::Svh;
10-
use rustc_data_structures::sync::MetadataRef;
1110
use rustc_hir as hir;
1211
use rustc_hir::def::{CtorKind, DefKind, DocLinkResMap};
1312
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, DefPathHash, StableCrateId};

0 commit comments

Comments
 (0)