Skip to content

Commit f8614c3

Browse files
authoredNov 27, 2016
Auto merge of #36340 - sfackler:slice-get-slice, r=alexcrichton
Implement RFC 1679 cc #35729 r? @alexcrichton
2 parents 9a86579 + 5377b5e commit f8614c3

File tree

7 files changed

+404
-185
lines changed

7 files changed

+404
-185
lines changed
 

‎src/libcollections/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#![feature(trusted_len)]
5555
#![feature(unicode)]
5656
#![feature(unique)]
57+
#![feature(slice_get_slice)]
5758
#![cfg_attr(test, feature(rand, test))]
5859

5960
#![no_std]

‎src/libcollections/slice.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ pub use core::slice::{SplitMut, ChunksMut, Split};
118118
pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
119119
#[stable(feature = "rust1", since = "1.0.0")]
120120
pub use core::slice::{from_raw_parts, from_raw_parts_mut};
121+
#[unstable(feature = "slice_get_slice", issue = "35729")]
122+
pub use core::slice::SliceIndex;
121123

122124
////////////////////////////////////////////////////////////////////////////////
123125
// Basic slice extension methods
@@ -353,7 +355,9 @@ impl<T> [T] {
353355
/// ```
354356
#[stable(feature = "rust1", since = "1.0.0")]
355357
#[inline]
356-
pub fn get(&self, index: usize) -> Option<&T> {
358+
pub fn get<I>(&self, index: I) -> Option<&I::Output>
359+
where I: SliceIndex<T>
360+
{
357361
core_slice::SliceExt::get(self, index)
358362
}
359363

@@ -372,7 +376,9 @@ impl<T> [T] {
372376
/// or `None` if the index is out of bounds
373377
#[stable(feature = "rust1", since = "1.0.0")]
374378
#[inline]
375-
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
379+
pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
380+
where I: SliceIndex<T>
381+
{
376382
core_slice::SliceExt::get_mut(self, index)
377383
}
378384

@@ -390,7 +396,9 @@ impl<T> [T] {
390396
/// ```
391397
#[stable(feature = "rust1", since = "1.0.0")]
392398
#[inline]
393-
pub unsafe fn get_unchecked(&self, index: usize) -> &T {
399+
pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
400+
where I: SliceIndex<T>
401+
{
394402
core_slice::SliceExt::get_unchecked(self, index)
395403
}
396404

@@ -410,7 +418,9 @@ impl<T> [T] {
410418
/// ```
411419
#[stable(feature = "rust1", since = "1.0.0")]
412420
#[inline]
413-
pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
421+
pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
422+
where I: SliceIndex<T>
423+
{
414424
core_slice::SliceExt::get_unchecked_mut(self, index)
415425
}
416426

‎src/libcore/slice.rs

Lines changed: 331 additions & 168 deletions
Large diffs are not rendered by default.

‎src/libcoretest/slice.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,47 @@ fn test_windows_last() {
180180
let c2 = v2.windows(2);
181181
assert_eq!(c2.last().unwrap()[0], 3);
182182
}
183+
184+
#[test]
185+
fn get_range() {
186+
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
187+
assert_eq!(v.get(..), Some(&[0, 1, 2, 3, 4, 5][..]));
188+
assert_eq!(v.get(..2), Some(&[0, 1][..]));
189+
assert_eq!(v.get(2..), Some(&[2, 3, 4, 5][..]));
190+
assert_eq!(v.get(1..4), Some(&[1, 2, 3][..]));
191+
assert_eq!(v.get(7..), None);
192+
assert_eq!(v.get(7..10), None);
193+
}
194+
195+
#[test]
196+
fn get_mut_range() {
197+
let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
198+
assert_eq!(v.get_mut(..), Some(&mut [0, 1, 2, 3, 4, 5][..]));
199+
assert_eq!(v.get_mut(..2), Some(&mut [0, 1][..]));
200+
assert_eq!(v.get_mut(2..), Some(&mut [2, 3, 4, 5][..]));
201+
assert_eq!(v.get_mut(1..4), Some(&mut [1, 2, 3][..]));
202+
assert_eq!(v.get_mut(7..), None);
203+
assert_eq!(v.get_mut(7..10), None);
204+
}
205+
206+
#[test]
207+
fn get_unchecked_range() {
208+
unsafe {
209+
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
210+
assert_eq!(v.get_unchecked(..), &[0, 1, 2, 3, 4, 5][..]);
211+
assert_eq!(v.get_unchecked(..2), &[0, 1][..]);
212+
assert_eq!(v.get_unchecked(2..), &[2, 3, 4, 5][..]);
213+
assert_eq!(v.get_unchecked(1..4), &[1, 2, 3][..]);
214+
}
215+
}
216+
217+
#[test]
218+
fn get_unchecked_mut_range() {
219+
unsafe {
220+
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
221+
assert_eq!(v.get_unchecked_mut(..), &mut [0, 1, 2, 3, 4, 5][..]);
222+
assert_eq!(v.get_unchecked_mut(..2), &mut [0, 1][..]);
223+
assert_eq!(v.get_unchecked_mut(2..), &mut[2, 3, 4, 5][..]);
224+
assert_eq!(v.get_unchecked_mut(1..4), &mut [1, 2, 3][..]);
225+
}
226+
}

‎src/test/compile-fail/indexing-requires-a-uint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
fn main() {
1515
fn bar<T>(_: T) {}
16-
[0][0u8]; //~ ERROR: `[{integer}]: std::ops::Index<u8>` is not satisfied
16+
[0][0u8]; //~ ERROR: the trait bound `u8: std::slice::SliceIndex<{integer}>` is not satisfied
1717

1818
[0][0]; // should infer to be a usize
1919

‎src/test/compile-fail/integral-indexing.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ pub fn main() {
1919
v[3i32]; //~ERROR : std::ops::Index<i32>` is not satisfied
2020
s.as_bytes()[3_usize];
2121
s.as_bytes()[3];
22-
s.as_bytes()[3u8]; //~ERROR : std::ops::Index<u8>` is not satisfied
23-
s.as_bytes()[3i8]; //~ERROR : std::ops::Index<i8>` is not satisfied
24-
s.as_bytes()[3u32]; //~ERROR : std::ops::Index<u32>` is not satisfied
25-
s.as_bytes()[3i32]; //~ERROR : std::ops::Index<i32>` is not satisfied
22+
s.as_bytes()[3u8]; //~ERROR : std::slice::SliceIndex<u8>` is not satisfied
23+
s.as_bytes()[3i8]; //~ERROR : std::slice::SliceIndex<u8>` is not satisfied
24+
s.as_bytes()[3u32]; //~ERROR : std::slice::SliceIndex<u8>` is not satisfied
25+
s.as_bytes()[3i32]; //~ERROR : std::slice::SliceIndex<u8>` is not satisfied
2626
}

‎src/test/compile-fail/on-unimplemented/slice-index.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
// Test new Index error message for slices
12+
// ignore-tidy-linelength
1213

1314
#![feature(rustc_attrs)]
1415

@@ -17,12 +18,12 @@ use std::ops::Index;
1718
#[rustc_error]
1819
fn main() {
1920
let x = &[1, 2, 3] as &[i32];
20-
x[1i32];
21-
//~^ ERROR E0277
22-
//~| NOTE the trait `std::ops::Index<i32>` is not implemented for `[i32]`
23-
//~| NOTE slice indices are of type `usize`
24-
x[..1i32];
25-
//~^ ERROR E0277
26-
//~| NOTE the trait `std::ops::Index<std::ops::RangeTo<i32>>` is not implemented for `[i32]`
27-
//~| NOTE slice indices are of type `usize`
21+
x[1i32]; //~ ERROR E0277
22+
//~| NOTE slice indices are of type `usize` or ranges of `usize`
23+
//~| NOTE trait `std::slice::SliceIndex<i32>` is not implemented for `i32`
24+
//~| NOTE required because of the requirements on the impl of `std::ops::Index<i32>`
25+
x[..1i32]; //~ ERROR E0277
26+
//~| NOTE slice indices are of type `usize` or ranges of `usize`
27+
//~| NOTE trait `std::slice::SliceIndex<i32>` is not implemented for `std::ops::RangeTo<i32>`
28+
//~| NOTE requirements on the impl of `std::ops::Index<std::ops::RangeTo<i32>>`
2829
}

0 commit comments

Comments
 (0)
Please sign in to comment.