diff options
| author | Jason Newcomb <jsnewcomb@pm.me> | 2025-02-21 16:01:19 -0500 |
|---|---|---|
| committer | Jason Newcomb <jsnewcomb@pm.me> | 2025-02-21 16:10:31 -0500 |
| commit | 162fb713ac66fef8f6a1d14bae9d1d4b35f76411 (patch) | |
| tree | 33ef24f64b9607373c6eb6a9686e39797f96dbfe /compiler/rustc_index | |
| parent | a74f3fb5fc955fe3876fa206ce2146cd355e1bb5 (diff) | |
| download | rust-162fb713ac66fef8f6a1d14bae9d1d4b35f76411.tar.gz rust-162fb713ac66fef8f6a1d14bae9d1d4b35f76411.zip | |
Allow SliceIndex to be indexed by ranges.
Diffstat (limited to 'compiler/rustc_index')
| -rw-r--r-- | compiler/rustc_index/src/idx.rs | 91 | ||||
| -rw-r--r-- | compiler/rustc_index/src/lib.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_index/src/slice.rs | 33 |
3 files changed, 113 insertions, 14 deletions
diff --git a/compiler/rustc_index/src/idx.rs b/compiler/rustc_index/src/idx.rs index b85160540d8..33f406e2113 100644 --- a/compiler/rustc_index/src/idx.rs +++ b/compiler/rustc_index/src/idx.rs @@ -1,5 +1,7 @@ use std::fmt::Debug; use std::hash::Hash; +use std::ops; +use std::slice::SliceIndex; /// Represents some newtyped `usize` wrapper. /// @@ -43,3 +45,92 @@ impl Idx for u32 { self as usize } } + +/// Helper trait for indexing operations with a custom index type. +pub trait IntoSliceIdx<I, T: ?Sized> { + type Output: SliceIndex<T>; + fn into_slice_idx(self) -> Self::Output; +} + +impl<I: Idx, T> IntoSliceIdx<I, [T]> for I { + type Output = usize; + #[inline] + fn into_slice_idx(self) -> Self::Output { + self.index() + } +} + +impl<I, T> IntoSliceIdx<I, [T]> for ops::RangeFull { + type Output = ops::RangeFull; + #[inline] + fn into_slice_idx(self) -> Self::Output { + self + } +} + +impl<I: Idx, T> IntoSliceIdx<I, [T]> for ops::Range<I> { + type Output = ops::Range<usize>; + #[inline] + fn into_slice_idx(self) -> Self::Output { + ops::Range { start: self.start.index(), end: self.end.index() } + } +} + +impl<I: Idx, T> IntoSliceIdx<I, [T]> for ops::RangeFrom<I> { + type Output = ops::RangeFrom<usize>; + #[inline] + fn into_slice_idx(self) -> Self::Output { + ops::RangeFrom { start: self.start.index() } + } +} + +impl<I: Idx, T> IntoSliceIdx<I, [T]> for ops::RangeTo<I> { + type Output = ops::RangeTo<usize>; + #[inline] + fn into_slice_idx(self) -> Self::Output { + ..self.end.index() + } +} + +impl<I: Idx, T> IntoSliceIdx<I, [T]> for ops::RangeInclusive<I> { + type Output = ops::RangeInclusive<usize>; + #[inline] + fn into_slice_idx(self) -> Self::Output { + ops::RangeInclusive::new(self.start().index(), self.end().index()) + } +} + +impl<I: Idx, T> IntoSliceIdx<I, [T]> for ops::RangeToInclusive<I> { + type Output = ops::RangeToInclusive<usize>; + #[inline] + fn into_slice_idx(self) -> Self::Output { + ..=self.end.index() + } +} + +#[cfg(feature = "nightly")] +impl<I: Idx, T> IntoSliceIdx<I, [T]> for core::range::Range<I> { + type Output = core::range::Range<usize>; + #[inline] + fn into_slice_idx(self) -> Self::Output { + core::range::Range { start: self.start.index(), end: self.end.index() } + } +} + +#[cfg(feature = "nightly")] +impl<I: Idx, T> IntoSliceIdx<I, [T]> for core::range::RangeFrom<I> { + type Output = core::range::RangeFrom<usize>; + #[inline] + fn into_slice_idx(self) -> Self::Output { + core::range::RangeFrom { start: self.start.index() } + } +} + +#[cfg(feature = "nightly")] +impl<I: Idx, T> IntoSliceIdx<I, [T]> for core::range::RangeInclusive<I> { + type Output = core::range::RangeInclusive<usize>; + #[inline] + fn into_slice_idx(self) -> Self::Output { + core::range::RangeInclusive { start: self.start.index(), end: self.end.index() } + } +} diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index cae55230b06..3441a5f65c7 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -2,6 +2,7 @@ #![cfg_attr(all(feature = "nightly", test), feature(stmt_expr_attributes))] #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", feature(extend_one, step_trait, test))] +#![cfg_attr(feature = "nightly", feature(new_range_api))] #![cfg_attr(feature = "nightly", feature(new_zeroed_alloc))] #![warn(unreachable_pub)] // tidy-alphabetical-end @@ -14,7 +15,7 @@ mod idx; mod slice; mod vec; -pub use idx::Idx; +pub use idx::{Idx, IntoSliceIdx}; pub use rustc_index_macros::newtype_index; pub use slice::IndexSlice; #[doc(no_inline)] diff --git a/compiler/rustc_index/src/slice.rs b/compiler/rustc_index/src/slice.rs index 956d32c9a69..cc8080ee697 100644 --- a/compiler/rustc_index/src/slice.rs +++ b/compiler/rustc_index/src/slice.rs @@ -1,8 +1,9 @@ +use std::fmt; use std::marker::PhantomData; use std::ops::{Index, IndexMut}; -use std::{fmt, slice}; +use std::slice::{self, SliceIndex}; -use crate::{Idx, IndexVec}; +use crate::{Idx, IndexVec, IntoSliceIdx}; /// A view into contiguous `T`s, indexed by `I` rather than by `usize`. /// @@ -99,13 +100,19 @@ impl<I: Idx, T> IndexSlice<I, T> { } #[inline] - pub fn get(&self, index: I) -> Option<&T> { - self.raw.get(index.index()) + pub fn get<R: IntoSliceIdx<I, [T]>>( + &self, + index: R, + ) -> Option<&<R::Output as SliceIndex<[T]>>::Output> { + self.raw.get(index.into_slice_idx()) } #[inline] - pub fn get_mut(&mut self, index: I) -> Option<&mut T> { - self.raw.get_mut(index.index()) + pub fn get_mut<R: IntoSliceIdx<I, [T]>>( + &mut self, + index: R, + ) -> Option<&mut <R::Output as SliceIndex<[T]>>::Output> { + self.raw.get_mut(index.into_slice_idx()) } /// Returns mutable references to two distinct elements, `a` and `b`. @@ -186,19 +193,19 @@ impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexSlice<I, T> { } } -impl<I: Idx, T> Index<I> for IndexSlice<I, T> { - type Output = T; +impl<I: Idx, T, R: IntoSliceIdx<I, [T]>> Index<R> for IndexSlice<I, T> { + type Output = <R::Output as SliceIndex<[T]>>::Output; #[inline] - fn index(&self, index: I) -> &T { - &self.raw[index.index()] + fn index(&self, index: R) -> &Self::Output { + &self.raw[index.into_slice_idx()] } } -impl<I: Idx, T> IndexMut<I> for IndexSlice<I, T> { +impl<I: Idx, T, R: IntoSliceIdx<I, [T]>> IndexMut<R> for IndexSlice<I, T> { #[inline] - fn index_mut(&mut self, index: I) -> &mut T { - &mut self.raw[index.index()] + fn index_mut(&mut self, index: R) -> &mut Self::Output { + &mut self.raw[index.into_slice_idx()] } } |
