From 5377b5e9c4270222cbbca99dae45715dd9d87d1c Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 19 Jul 2016 10:50:52 +0200 Subject: [PATCH] Overload get{,_mut}{,_unchecked} --- src/libcollections/lib.rs | 1 + src/libcollections/slice.rs | 18 +- src/libcore/slice.rs | 499 ++++++++++++------ src/libcoretest/slice.rs | 44 ++ .../compile-fail/indexing-requires-a-uint.rs | 2 +- src/test/compile-fail/integral-indexing.rs | 8 +- .../on-unimplemented/slice-index.rs | 17 +- 7 files changed, 404 insertions(+), 185 deletions(-) diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index f6d83b25b0d89..08288b4de8bde 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -54,6 +54,7 @@ #![feature(trusted_len)] #![feature(unicode)] #![feature(unique)] +#![feature(slice_get_slice)] #![cfg_attr(test, feature(rand, test))] #![no_std] diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 75796cf94bfc2..e615e780d2b5c 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -118,6 +118,8 @@ pub use core::slice::{SplitMut, ChunksMut, Split}; pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::slice::{from_raw_parts, from_raw_parts_mut}; +#[unstable(feature = "slice_get_slice", issue = "35729")] +pub use core::slice::SliceIndex; //////////////////////////////////////////////////////////////////////////////// // Basic slice extension methods @@ -353,7 +355,9 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn get(&self, index: usize) -> Option<&T> { + pub fn get(&self, index: I) -> Option<&I::Output> + where I: SliceIndex + { core_slice::SliceExt::get(self, index) } @@ -372,7 +376,9 @@ impl [T] { /// or `None` if the index is out of bounds #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn get_mut(&mut self, index: usize) -> Option<&mut T> { + pub fn get_mut(&mut self, index: I) -> Option<&mut I::Output> + where I: SliceIndex + { core_slice::SliceExt::get_mut(self, index) } @@ -390,7 +396,9 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub unsafe fn get_unchecked(&self, index: usize) -> &T { + pub unsafe fn get_unchecked(&self, index: I) -> &I::Output + where I: SliceIndex + { core_slice::SliceExt::get_unchecked(self, index) } @@ -410,7 +418,9 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T { + pub unsafe fn get_unchecked_mut(&mut self, index: I) -> &mut I::Output + where I: SliceIndex + { core_slice::SliceExt::get_unchecked_mut(self, index) } diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index ede45111ebbc5..a4a90e7a9da7a 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -38,10 +38,14 @@ use cmp; use fmt; use intrinsics::assume; use iter::*; -use ops::{self, RangeFull}; +use ops::{FnMut, self}; +use option::Option; +use option::Option::{None, Some}; +use result::Result; +use result::Result::{Ok, Err}; use ptr; use mem; -use marker; +use marker::{Copy, Send, Sync, Sized, self}; use iter_private::TrustedRandomAccess; #[repr(C)] @@ -80,7 +84,8 @@ pub trait SliceExt { #[stable(feature = "core", since = "1.6.0")] fn chunks(&self, size: usize) -> Chunks; #[stable(feature = "core", since = "1.6.0")] - fn get(&self, index: usize) -> Option<&Self::Item>; + fn get(&self, index: I) -> Option<&I::Output> + where I: SliceIndex; #[stable(feature = "core", since = "1.6.0")] fn first(&self) -> Option<&Self::Item>; #[stable(feature = "core", since = "1.6.0")] @@ -90,7 +95,8 @@ pub trait SliceExt { #[stable(feature = "core", since = "1.6.0")] fn last(&self) -> Option<&Self::Item>; #[stable(feature = "core", since = "1.6.0")] - unsafe fn get_unchecked(&self, index: usize) -> &Self::Item; + unsafe fn get_unchecked(&self, index: I) -> &I::Output + where I: SliceIndex; #[stable(feature = "core", since = "1.6.0")] fn as_ptr(&self) -> *const Self::Item; #[stable(feature = "core", since = "1.6.0")] @@ -108,7 +114,8 @@ pub trait SliceExt { #[stable(feature = "core", since = "1.6.0")] fn is_empty(&self) -> bool { self.len() == 0 } #[stable(feature = "core", since = "1.6.0")] - fn get_mut(&mut self, index: usize) -> Option<&mut Self::Item>; + fn get_mut(&mut self, index: I) -> Option<&mut I::Output> + where I: SliceIndex; #[stable(feature = "core", since = "1.6.0")] fn iter_mut(&mut self) -> IterMut; #[stable(feature = "core", since = "1.6.0")] @@ -137,7 +144,8 @@ pub trait SliceExt { #[stable(feature = "core", since = "1.6.0")] fn reverse(&mut self); #[stable(feature = "core", since = "1.6.0")] - unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut Self::Item; + unsafe fn get_unchecked_mut(&mut self, index: I) -> &mut I::Output + where I: SliceIndex; #[stable(feature = "core", since = "1.6.0")] fn as_mut_ptr(&mut self) -> *mut Self::Item; @@ -258,8 +266,10 @@ impl SliceExt for [T] { } #[inline] - fn get(&self, index: usize) -> Option<&T> { - if index < self.len() { Some(&self[index]) } else { None } + fn get(&self, index: I) -> Option<&I::Output> + where I: SliceIndex + { + index.get(self) } #[inline] @@ -284,8 +294,10 @@ impl SliceExt for [T] { } #[inline] - unsafe fn get_unchecked(&self, index: usize) -> &T { - &*(self.as_ptr().offset(index as isize)) + unsafe fn get_unchecked(&self, index: I) -> &I::Output + where I: SliceIndex + { + index.get_unchecked(self) } #[inline] @@ -323,8 +335,10 @@ impl SliceExt for [T] { } #[inline] - fn get_mut(&mut self, index: usize) -> Option<&mut T> { - if index < self.len() { Some(&mut self[index]) } else { None } + fn get_mut(&mut self, index: I) -> Option<&mut I::Output> + where I: SliceIndex + { + index.get_mut(self) } #[inline] @@ -451,8 +465,10 @@ impl SliceExt for [T] { } #[inline] - unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T { - &mut *self.as_mut_ptr().offset(index as isize) + unsafe fn get_unchecked_mut(&mut self, index: I) -> &mut I::Output + where I: SliceIndex + { + index.get_unchecked_mut(self) } #[inline] @@ -515,23 +531,26 @@ impl SliceExt for [T] { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "slice indices are of type `usize`"] -impl ops::Index for [T] { - type Output = T; +#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"] +impl ops::Index for [T] + where I: SliceIndex +{ + type Output = I::Output; - fn index(&self, index: usize) -> &T { - // NB built-in indexing - &(*self)[index] + #[inline] + fn index(&self, index: I) -> &I::Output { + index.index(self) } } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "slice indices are of type `usize`"] -impl ops::IndexMut for [T] { +#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"] +impl ops::IndexMut for [T] + where I: SliceIndex +{ #[inline] - fn index_mut(&mut self, index: usize) -> &mut T { - // NB built-in indexing - &mut (*self)[index] + fn index_mut(&mut self, index: I) -> &mut I::Output { + index.index_mut(self) } } @@ -547,205 +566,349 @@ fn slice_index_order_fail(index: usize, end: usize) -> ! { panic!("slice index starts at {} but ends at {}", index, end); } +/// A helper trait used for indexing operations. +#[unstable(feature = "slice_get_slice", issue = "35729")] +#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"] +pub trait SliceIndex { + /// The output type returned by methods. + type Output: ?Sized; -/// Implements slicing with syntax `&self[begin .. end]`. -/// -/// Returns a slice of self for the index range [`begin`..`end`). -/// -/// This operation is `O(1)`. -/// -/// # Panics -/// -/// Requires that `begin <= end` and `end <= self.len()`, -/// otherwise slicing will panic. -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "slice indices are of type `usize`"] -impl ops::Index> for [T] { + /// Returns a shared reference to the output at this location, if in + /// bounds. + fn get(self, slice: &[T]) -> Option<&Self::Output>; + + /// Returns a mutable reference to the output at this location, if in + /// bounds. + fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output>; + + /// Returns a shared reference to the output at this location, without + /// performing any bounds checking. + unsafe fn get_unchecked(self, slice: &[T]) -> &Self::Output; + + /// Returns a mutable reference to the output at this location, without + /// performing any bounds checking. + unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut Self::Output; + + /// Returns a shared reference to the output at this location, panicking + /// if out of bounds. + fn index(self, slice: &[T]) -> &Self::Output; + + /// Returns a mutable reference to the output at this location, panicking + /// if out of bounds. + fn index_mut(self, slice: &mut [T]) -> &mut Self::Output; +} + +#[stable(feature = "slice-get-slice-impls", since = "1.13.0")] +impl SliceIndex for usize { + type Output = T; + + #[inline] + fn get(self, slice: &[T]) -> Option<&T> { + if self < slice.len() { + unsafe { + Some(self.get_unchecked(slice)) + } + } else { + None + } + } + + #[inline] + fn get_mut(self, slice: &mut [T]) -> Option<&mut T> { + if self < slice.len() { + unsafe { + Some(self.get_unchecked_mut(slice)) + } + } else { + None + } + } + + #[inline] + unsafe fn get_unchecked(self, slice: &[T]) -> &T { + &*slice.as_ptr().offset(self as isize) + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut T { + &mut *slice.as_mut_ptr().offset(self as isize) + } + + #[inline] + fn index(self, slice: &[T]) -> &T { + // NB: use intrinsic indexing + &(*slice)[self] + } + + #[inline] + fn index_mut(self, slice: &mut [T]) -> &mut T { + // NB: use intrinsic indexing + &mut (*slice)[self] + } +} + +#[stable(feature = "slice-get-slice-impls", since = "1.13.0")] +impl SliceIndex for ops::Range { type Output = [T]; #[inline] - fn index(&self, index: ops::Range) -> &[T] { - if index.start > index.end { - slice_index_order_fail(index.start, index.end); - } else if index.end > self.len() { - slice_index_len_fail(index.end, self.len()); + fn get(self, slice: &[T]) -> Option<&[T]> { + if self.start > self.end || self.end > slice.len() { + None + } else { + unsafe { + Some(self.get_unchecked(slice)) + } + } + } + + #[inline] + fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { + if self.start > self.end || self.end > slice.len() { + None + } else { + unsafe { + Some(self.get_unchecked_mut(slice)) + } + } + } + + #[inline] + unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { + from_raw_parts(slice.as_ptr().offset(self.start as isize), self.end - self.start) + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { + from_raw_parts_mut(slice.as_mut_ptr().offset(self.start as isize), self.end - self.start) + } + + #[inline] + fn index(self, slice: &[T]) -> &[T] { + if self.start > self.end { + slice_index_order_fail(self.start, self.end); + } else if self.end > slice.len() { + slice_index_len_fail(self.end, slice.len()); + } + unsafe { + self.get_unchecked(slice) + } + } + + #[inline] + fn index_mut(self, slice: &mut [T]) -> &mut [T] { + if self.start > self.end { + slice_index_order_fail(self.start, self.end); + } else if self.end > slice.len() { + slice_index_len_fail(self.end, slice.len()); } unsafe { - from_raw_parts ( - self.as_ptr().offset(index.start as isize), - index.end - index.start - ) + self.get_unchecked_mut(slice) } } } -/// Implements slicing with syntax `&self[.. end]`. -/// -/// Returns a slice of self from the beginning until but not including -/// the index `end`. -/// -/// Equivalent to `&self[0 .. end]` -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "slice indices are of type `usize`"] -impl ops::Index> for [T] { +#[stable(feature = "slice-get-slice-impls", since = "1.13.0")] +impl SliceIndex for ops::RangeTo { type Output = [T]; #[inline] - fn index(&self, index: ops::RangeTo) -> &[T] { - self.index(0 .. index.end) + fn get(self, slice: &[T]) -> Option<&[T]> { + (0..self.end).get(slice) + } + + #[inline] + fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { + (0..self.end).get_mut(slice) + } + + #[inline] + unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { + (0..self.end).get_unchecked(slice) + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { + (0..self.end).get_unchecked_mut(slice) + } + + #[inline] + fn index(self, slice: &[T]) -> &[T] { + (0..self.end).index(slice) + } + + #[inline] + fn index_mut(self, slice: &mut [T]) -> &mut [T] { + (0..self.end).index_mut(slice) } } -/// Implements slicing with syntax `&self[begin ..]`. -/// -/// Returns a slice of self from and including the index `begin` until the end. -/// -/// Equivalent to `&self[begin .. self.len()]` -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "slice indices are of type `usize`"] -impl ops::Index> for [T] { +#[stable(feature = "slice-get-slice-impls", since = "1.13.0")] +impl SliceIndex for ops::RangeFrom { type Output = [T]; #[inline] - fn index(&self, index: ops::RangeFrom) -> &[T] { - self.index(index.start .. self.len()) + fn get(self, slice: &[T]) -> Option<&[T]> { + (self.start..slice.len()).get(slice) + } + + #[inline] + fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { + (self.start..slice.len()).get_mut(slice) + } + + #[inline] + unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { + (self.start..slice.len()).get_unchecked(slice) + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { + (self.start..slice.len()).get_unchecked_mut(slice) + } + + #[inline] + fn index(self, slice: &[T]) -> &[T] { + (self.start..slice.len()).index(slice) + } + + #[inline] + fn index_mut(self, slice: &mut [T]) -> &mut [T] { + (self.start..slice.len()).index_mut(slice) } } -/// Implements slicing with syntax `&self[..]`. -/// -/// Returns a slice of the whole slice. This operation cannot panic. -/// -/// Equivalent to `&self[0 .. self.len()]` -#[stable(feature = "rust1", since = "1.0.0")] -impl ops::Index for [T] { +#[stable(feature = "slice-get-slice-impls", since = "1.13.0")] +impl SliceIndex for ops::RangeFull { type Output = [T]; #[inline] - fn index(&self, _index: RangeFull) -> &[T] { - self + fn get(self, slice: &[T]) -> Option<&[T]> { + Some(slice) + } + + #[inline] + fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { + Some(slice) + } + + #[inline] + unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { + slice + } + + #[inline] + unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { + slice + } + + #[inline] + fn index(self, slice: &[T]) -> &[T] { + slice + } + + #[inline] + fn index_mut(self, slice: &mut [T]) -> &mut [T] { + slice } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] -#[rustc_on_unimplemented = "slice indices are of type `usize`"] -impl ops::Index> for [T] { + +#[stable(feature = "slice-get-slice-impls", since = "1.13.0")] +impl SliceIndex for ops::RangeInclusive { type Output = [T]; #[inline] - fn index(&self, index: ops::RangeInclusive) -> &[T] { - match index { + fn get(self, slice: &[T]) -> Option<&[T]> { + match self { + ops::RangeInclusive::Empty { .. } => Some(&[]), + ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => None, + ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).get(slice), + } + } + + #[inline] + fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { + match self { + ops::RangeInclusive::Empty { .. } => Some(&mut []), + ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => None, + ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).get_mut(slice), + } + } + + #[inline] + unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { + match self { ops::RangeInclusive::Empty { .. } => &[], - ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => - panic!("attempted to index slice up to maximum usize"), - ops::RangeInclusive::NonEmpty { start, end } => - self.index(start .. end+1) + ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).get_unchecked(slice), } } -} -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] -#[rustc_on_unimplemented = "slice indices are of type `usize`"] -impl ops::Index> for [T] { - type Output = [T]; #[inline] - fn index(&self, index: ops::RangeToInclusive) -> &[T] { - self.index(0...index.end) + unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { + match self { + ops::RangeInclusive::Empty { .. } => &mut [], + ops::RangeInclusive::NonEmpty { start, end } => { + (start..end + 1).get_unchecked_mut(slice) + } + } } -} -/// Implements mutable slicing with syntax `&mut self[begin .. end]`. -/// -/// Returns a slice of self for the index range [`begin`..`end`). -/// -/// This operation is `O(1)`. -/// -/// # Panics -/// -/// Requires that `begin <= end` and `end <= self.len()`, -/// otherwise slicing will panic. -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "slice indices are of type `usize`"] -impl ops::IndexMut> for [T] { #[inline] - fn index_mut(&mut self, index: ops::Range) -> &mut [T] { - if index.start > index.end { - slice_index_order_fail(index.start, index.end); - } else if index.end > self.len() { - slice_index_len_fail(index.end, self.len()); + fn index(self, slice: &[T]) -> &[T] { + match self { + ops::RangeInclusive::Empty { .. } => &[], + ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => { + panic!("attempted to index slice up to maximum usize"); + }, + ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).index(slice), } - unsafe { - from_raw_parts_mut( - self.as_mut_ptr().offset(index.start as isize), - index.end - index.start - ) + } + + #[inline] + fn index_mut(self, slice: &mut [T]) -> &mut [T] { + match self { + ops::RangeInclusive::Empty { .. } => &mut [], + ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => { + panic!("attempted to index slice up to maximum usize"); + }, + ops::RangeInclusive::NonEmpty { start, end } => (start..end + 1).index_mut(slice), } } } -/// Implements mutable slicing with syntax `&mut self[.. end]`. -/// -/// Returns a slice of self from the beginning until but not including -/// the index `end`. -/// -/// Equivalent to `&mut self[0 .. end]` -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "slice indices are of type `usize`"] -impl ops::IndexMut> for [T] { +#[stable(feature = "slice-get-slice-impls", since = "1.13.0")] +impl SliceIndex for ops::RangeToInclusive { + type Output = [T]; + #[inline] - fn index_mut(&mut self, index: ops::RangeTo) -> &mut [T] { - self.index_mut(0 .. index.end) + fn get(self, slice: &[T]) -> Option<&[T]> { + (0...self.end).get(slice) } -} -/// Implements mutable slicing with syntax `&mut self[begin ..]`. -/// -/// Returns a slice of self from and including the index `begin` until the end. -/// -/// Equivalent to `&mut self[begin .. self.len()]` -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "slice indices are of type `usize`"] -impl ops::IndexMut> for [T] { #[inline] - fn index_mut(&mut self, index: ops::RangeFrom) -> &mut [T] { - let len = self.len(); - self.index_mut(index.start .. len) + fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> { + (0...self.end).get_mut(slice) } -} -/// Implements mutable slicing with syntax `&mut self[..]`. -/// -/// Returns a slice of the whole slice. This operation can not panic. -/// -/// Equivalent to `&mut self[0 .. self.len()]` -#[stable(feature = "rust1", since = "1.0.0")] -impl ops::IndexMut for [T] { #[inline] - fn index_mut(&mut self, _index: RangeFull) -> &mut [T] { - self + unsafe fn get_unchecked(self, slice: &[T]) -> &[T] { + (0...self.end).get_unchecked(slice) } -} -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] -#[rustc_on_unimplemented = "slice indices are of type `usize`"] -impl ops::IndexMut> for [T] { #[inline] - fn index_mut(&mut self, index: ops::RangeInclusive) -> &mut [T] { - match index { - ops::RangeInclusive::Empty { .. } => &mut [], - ops::RangeInclusive::NonEmpty { end, .. } if end == usize::max_value() => - panic!("attempted to index slice up to maximum usize"), - ops::RangeInclusive::NonEmpty { start, end } => - self.index_mut(start .. end+1) - } + unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] { + (0...self.end).get_unchecked_mut(slice) } -} -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] -#[rustc_on_unimplemented = "slice indices are of type `usize`"] -impl ops::IndexMut> for [T] { + + #[inline] + fn index(self, slice: &[T]) -> &[T] { + (0...self.end).index(slice) + } + #[inline] - fn index_mut(&mut self, index: ops::RangeToInclusive) -> &mut [T] { - self.index_mut(0...index.end) + fn index_mut(self, slice: &mut [T]) -> &mut [T] { + (0...self.end).index_mut(slice) } } diff --git a/src/libcoretest/slice.rs b/src/libcoretest/slice.rs index f82ab44adad00..ad39e6b081b42 100644 --- a/src/libcoretest/slice.rs +++ b/src/libcoretest/slice.rs @@ -180,3 +180,47 @@ fn test_windows_last() { let c2 = v2.windows(2); assert_eq!(c2.last().unwrap()[0], 3); } + +#[test] +fn get_range() { + let v: &[i32] = &[0, 1, 2, 3, 4, 5]; + assert_eq!(v.get(..), Some(&[0, 1, 2, 3, 4, 5][..])); + assert_eq!(v.get(..2), Some(&[0, 1][..])); + assert_eq!(v.get(2..), Some(&[2, 3, 4, 5][..])); + assert_eq!(v.get(1..4), Some(&[1, 2, 3][..])); + assert_eq!(v.get(7..), None); + assert_eq!(v.get(7..10), None); +} + +#[test] +fn get_mut_range() { + let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5]; + assert_eq!(v.get_mut(..), Some(&mut [0, 1, 2, 3, 4, 5][..])); + assert_eq!(v.get_mut(..2), Some(&mut [0, 1][..])); + assert_eq!(v.get_mut(2..), Some(&mut [2, 3, 4, 5][..])); + assert_eq!(v.get_mut(1..4), Some(&mut [1, 2, 3][..])); + assert_eq!(v.get_mut(7..), None); + assert_eq!(v.get_mut(7..10), None); +} + +#[test] +fn get_unchecked_range() { + unsafe { + let v: &[i32] = &[0, 1, 2, 3, 4, 5]; + assert_eq!(v.get_unchecked(..), &[0, 1, 2, 3, 4, 5][..]); + assert_eq!(v.get_unchecked(..2), &[0, 1][..]); + assert_eq!(v.get_unchecked(2..), &[2, 3, 4, 5][..]); + assert_eq!(v.get_unchecked(1..4), &[1, 2, 3][..]); + } +} + +#[test] +fn get_unchecked_mut_range() { + unsafe { + let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5]; + assert_eq!(v.get_unchecked_mut(..), &mut [0, 1, 2, 3, 4, 5][..]); + assert_eq!(v.get_unchecked_mut(..2), &mut [0, 1][..]); + assert_eq!(v.get_unchecked_mut(2..), &mut[2, 3, 4, 5][..]); + assert_eq!(v.get_unchecked_mut(1..4), &mut [1, 2, 3][..]); + } +} diff --git a/src/test/compile-fail/indexing-requires-a-uint.rs b/src/test/compile-fail/indexing-requires-a-uint.rs index 61d54b3f8e4fd..1889d76c03c03 100644 --- a/src/test/compile-fail/indexing-requires-a-uint.rs +++ b/src/test/compile-fail/indexing-requires-a-uint.rs @@ -13,7 +13,7 @@ fn main() { fn bar(_: T) {} - [0][0u8]; //~ ERROR: `[{integer}]: std::ops::Index` is not satisfied + [0][0u8]; //~ ERROR: the trait bound `u8: std::slice::SliceIndex<{integer}>` is not satisfied [0][0]; // should infer to be a usize diff --git a/src/test/compile-fail/integral-indexing.rs b/src/test/compile-fail/integral-indexing.rs index c8f33c3caf8d3..1815d0e978a94 100644 --- a/src/test/compile-fail/integral-indexing.rs +++ b/src/test/compile-fail/integral-indexing.rs @@ -19,8 +19,8 @@ pub fn main() { v[3i32]; //~ERROR : std::ops::Index` is not satisfied s.as_bytes()[3_usize]; s.as_bytes()[3]; - s.as_bytes()[3u8]; //~ERROR : std::ops::Index` is not satisfied - s.as_bytes()[3i8]; //~ERROR : std::ops::Index` is not satisfied - s.as_bytes()[3u32]; //~ERROR : std::ops::Index` is not satisfied - s.as_bytes()[3i32]; //~ERROR : std::ops::Index` is not satisfied + s.as_bytes()[3u8]; //~ERROR : std::slice::SliceIndex` is not satisfied + s.as_bytes()[3i8]; //~ERROR : std::slice::SliceIndex` is not satisfied + s.as_bytes()[3u32]; //~ERROR : std::slice::SliceIndex` is not satisfied + s.as_bytes()[3i32]; //~ERROR : std::slice::SliceIndex` is not satisfied } diff --git a/src/test/compile-fail/on-unimplemented/slice-index.rs b/src/test/compile-fail/on-unimplemented/slice-index.rs index d528d0e626a79..d28b823ddc145 100644 --- a/src/test/compile-fail/on-unimplemented/slice-index.rs +++ b/src/test/compile-fail/on-unimplemented/slice-index.rs @@ -9,6 +9,7 @@ // except according to those terms. // Test new Index error message for slices +// ignore-tidy-linelength #![feature(rustc_attrs)] @@ -17,12 +18,12 @@ use std::ops::Index; #[rustc_error] fn main() { let x = &[1, 2, 3] as &[i32]; - x[1i32]; - //~^ ERROR E0277 - //~| NOTE the trait `std::ops::Index` is not implemented for `[i32]` - //~| NOTE slice indices are of type `usize` - x[..1i32]; - //~^ ERROR E0277 - //~| NOTE the trait `std::ops::Index>` is not implemented for `[i32]` - //~| NOTE slice indices are of type `usize` + x[1i32]; //~ ERROR E0277 + //~| NOTE slice indices are of type `usize` or ranges of `usize` + //~| NOTE trait `std::slice::SliceIndex` is not implemented for `i32` + //~| NOTE required because of the requirements on the impl of `std::ops::Index` + x[..1i32]; //~ ERROR E0277 + //~| NOTE slice indices are of type `usize` or ranges of `usize` + //~| NOTE trait `std::slice::SliceIndex` is not implemented for `std::ops::RangeTo` + //~| NOTE requirements on the impl of `std::ops::Index>` }