about summary refs log tree commit diff
path: root/compiler/rustc_index/src/idx.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_index/src/idx.rs')
-rw-r--r--compiler/rustc_index/src/idx.rs91
1 files changed, 91 insertions, 0 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() }
+    }
+}