diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 63f9a8097ba3a..eec7f01c0c4df 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1985,6 +1985,8 @@ mod private_slice_index { #[stable(feature = "slice_get_slice", since = "1.28.0")] impl Sealed for usize {} #[stable(feature = "slice_get_slice", since = "1.28.0")] + impl> Sealed for R {} + #[stable(feature = "slice_get_slice", since = "1.28.0")] impl Sealed for ops::Range {} #[stable(feature = "slice_get_slice", since = "1.28.0")] impl Sealed for ops::RangeTo {} @@ -2086,10 +2088,61 @@ impl SliceIndex<[T]> for usize { } } +// Given a RangeBounds, pick the appropriate concrete RangeXXX type and call the +// given method on an instance of that concrete type. +macro_rules! call_method_on_range_bounds { + ($slf:ident, $method:ident, $slc:ident) => ( + match ($slf.start_bound(), $slf.end_bound()) { + (ops::Bound::Included(x), ops::Bound::Included(y)) => (*x..=*y).$method($slc), + (ops::Bound::Included(x), ops::Bound::Excluded(y)) => (*x..*y).$method($slc), + (ops::Bound::Included(x), ops::Bound::Unbounded) => (*x..).$method($slc), + (ops::Bound::Excluded(x), ops::Bound::Included(y)) => ((x+1)..=*y).$method($slc), + (ops::Bound::Excluded(x), ops::Bound::Excluded(y)) => ((x+1)..*y).$method($slc), + (ops::Bound::Excluded(x), ops::Bound::Unbounded) => ((x+1)..).$method($slc), + (ops::Bound::Unbounded, ops::Bound::Included(y)) => (..=*y).$method($slc), + (ops::Bound::Unbounded, ops::Bound::Excluded(y)) => (..*y).$method($slc), + (ops::Bound::Unbounded, ops::Bound::Unbounded) => (..).$method($slc), + } + ); +} + #[stable(feature = "slice-get-slice-impls", since = "1.15.0")] -impl SliceIndex<[T]> for ops::Range { +impl> SliceIndex<[T]> for R { type Output = [T]; + #[inline] + default fn get(self, slice: &[T]) -> Option<&[T]> { + call_method_on_range_bounds!(self, get, slice) + } + + #[inline] + default fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { + call_method_on_range_bounds!(self, get_mut, slice) + } + + #[inline] + default unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { + call_method_on_range_bounds!(self, get_unchecked, slice) + } + + #[inline] + default unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { + call_method_on_range_bounds!(self, get_unchecked_mut, slice) + } + + #[inline] + default fn index(self, slice: &[T]) -> &[T] { + call_method_on_range_bounds!(self, index, slice) + } + + #[inline] + default fn index_mut(self, slice: &mut [T]) -> &mut [T] { + call_method_on_range_bounds!(self, index_mut, slice) + } +} + +#[stable(feature = "slice-get-slice-impls", since = "1.15.0")] +impl SliceIndex<[T]> for ops::Range { #[inline] fn get(self, slice: &[T]) -> Option<&[T]> { if self.start > self.end || self.end > slice.len() { @@ -2149,8 +2202,6 @@ impl SliceIndex<[T]> for ops::Range { #[stable(feature = "slice-get-slice-impls", since = "1.15.0")] impl SliceIndex<[T]> for ops::RangeTo { - type Output = [T]; - #[inline] fn get(self, slice: &[T]) -> Option<&[T]> { (0..self.end).get(slice) @@ -2184,8 +2235,6 @@ impl SliceIndex<[T]> for ops::RangeTo { #[stable(feature = "slice-get-slice-impls", since = "1.15.0")] impl SliceIndex<[T]> for ops::RangeFrom { - type Output = [T]; - #[inline] fn get(self, slice: &[T]) -> Option<&[T]> { (self.start..slice.len()).get(slice) @@ -2219,8 +2268,6 @@ impl SliceIndex<[T]> for ops::RangeFrom { #[stable(feature = "slice-get-slice-impls", since = "1.15.0")] impl SliceIndex<[T]> for ops::RangeFull { - type Output = [T]; - #[inline] fn get(self, slice: &[T]) -> Option<&[T]> { Some(slice) @@ -2255,8 +2302,6 @@ impl SliceIndex<[T]> for ops::RangeFull { #[stable(feature = "inclusive_range", since = "1.26.0")] impl SliceIndex<[T]> for ops::RangeInclusive { - type Output = [T]; - #[inline] fn get(self, slice: &[T]) -> Option<&[T]> { if self.end == usize::max_value() { None } @@ -2294,8 +2339,6 @@ impl SliceIndex<[T]> for ops::RangeInclusive { #[stable(feature = "inclusive_range", since = "1.26.0")] impl SliceIndex<[T]> for ops::RangeToInclusive { - type Output = [T]; - #[inline] fn get(self, slice: &[T]) -> Option<&[T]> { (0..=self.end).get(slice)