diff options
| author | Scott McMurray <scottmcm@users.noreply.github.com> | 2023-03-31 00:32:44 -0700 |
|---|---|---|
| committer | Scott McMurray <scottmcm@users.noreply.github.com> | 2023-04-02 17:35:37 -0700 |
| commit | a2ee7592d6b7c0daa62b7870ade85e0cc0acca05 (patch) | |
| tree | 4ab6bedbd53989ea3c1b556e4d61c33f469c536b /compiler/rustc_index/src | |
| parent | a93bcdc30771340dfff914a1cf48556886ad33a6 (diff) | |
| download | rust-a2ee7592d6b7c0daa62b7870ade85e0cc0acca05.tar.gz rust-a2ee7592d6b7c0daa62b7870ade85e0cc0acca05.zip | |
Use `&IndexSlice` instead of `&IndexVec` where possible
All the same reasons as for `[T]`: more general, less pointer chasing, and `&mut IndexSlice` emphasizes that it doesn't change *length*.
Diffstat (limited to 'compiler/rustc_index/src')
| -rw-r--r-- | compiler/rustc_index/src/vec.rs | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 6caae059f4a..5945de2302a 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -1,6 +1,7 @@ #[cfg(feature = "rustc_serialize")] use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; +use std::borrow::{Borrow, BorrowMut}; use std::fmt; use std::fmt::Debug; use std::hash::Hash; @@ -51,6 +52,12 @@ impl Idx for u32 { } } +/// An owned contiguous collection of `T`s, indexed by `I` rather than by `usize`. +/// +/// While it's possible to use `u32` or `usize` directly for `I`, +/// you almost certainly want to use a [`newtype_index!`]-generated type instead. +/// +/// [`newtype_index!`]: ../macro.newtype_index.html #[derive(Clone, PartialEq, Eq, Hash)] #[repr(transparent)] pub struct IndexVec<I: Idx, T> { @@ -58,6 +65,13 @@ pub struct IndexVec<I: Idx, T> { _marker: PhantomData<fn(&I)>, } +/// A view into contiguous `T`s, indexed by `I` rather than by `usize`. +/// +/// One common pattern you'll see is code that uses [`IndexVec::from_elem`] +/// to create the storage needed for a particular "universe" (aka the set of all +/// the possible keys that need an associated value) then passes that working +/// area as `&mut IndexSlice<I, T>` to clarify that nothing will be added nor +/// removed during processing (and, as a bonus, to chase fewer pointers). #[derive(PartialEq, Eq, Hash)] #[repr(transparent)] pub struct IndexSlice<I: Idx, T> { @@ -116,7 +130,7 @@ impl<I: Idx, T> IndexVec<I, T> { } #[inline] - pub fn from_elem<S>(elem: T, universe: &IndexVec<I, S>) -> Self + pub fn from_elem<S>(elem: T, universe: &IndexSlice<I, S>) -> Self where T: Clone, { @@ -244,6 +258,30 @@ impl<I: Idx, T> DerefMut for IndexVec<I, T> { } } +impl<I: Idx, T> Borrow<IndexSlice<I, T>> for IndexVec<I, T> { + fn borrow(&self) -> &IndexSlice<I, T> { + self + } +} + +impl<I: Idx, T> BorrowMut<IndexSlice<I, T>> for IndexVec<I, T> { + fn borrow_mut(&mut self) -> &mut IndexSlice<I, T> { + self + } +} + +impl<I: Idx, T: Clone> ToOwned for IndexSlice<I, T> { + type Owned = IndexVec<I, T>; + + fn to_owned(&self) -> IndexVec<I, T> { + IndexVec::from_raw(self.raw.to_owned()) + } + + fn clone_into(&self, target: &mut IndexVec<I, T>) { + self.raw.clone_into(&mut target.raw) + } +} + impl<I: Idx, T> IndexSlice<I, T> { #[inline] pub fn from_raw(raw: &[T]) -> &Self { @@ -388,7 +426,7 @@ impl<I: Idx, T: Clone> IndexVec<I, T> { } } -impl<I: Idx, T: Ord> IndexVec<I, T> { +impl<I: Idx, T: Ord> IndexSlice<I, T> { #[inline] pub fn binary_search(&self, value: &T) -> Result<I, I> { match self.raw.binary_search(value) { |
