Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use SliceIndex for str's Index/IndexMut impls #55683

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2305,7 +2305,6 @@ impl [u8] {
}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
impl<T, I> ops::Index<I> for [T]
where I: SliceIndex<[T]>
{
Expand All @@ -2318,7 +2317,6 @@ impl<T, I> ops::Index<I> for [T]
}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
impl<T, I> ops::IndexMut<I> for [T]
where I: SliceIndex<[T]>
{
Expand Down Expand Up @@ -2369,7 +2367,6 @@ mod private_slice_index {

/// A helper trait used for indexing operations.
#[stable(feature = "slice_get_slice", since = "1.28.0")]
#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
/// The output type returned by methods.
#[stable(feature = "slice_get_slice", since = "1.28.0")]
Expand Down
190 changes: 13 additions & 177 deletions src/libcore/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1630,190 +1630,26 @@ mod traits {
}
}

/// Implements substring slicing with syntax `&self[begin .. end]`.
///
/// Returns a slice of the given string from the byte range
/// [`begin`..`end`).
///
/// This operation is `O(1)`.
///
/// # Panics
///
/// Panics if `begin` or `end` does not point to the starting
/// byte offset of a character (as defined by `is_char_boundary`).
/// Requires that `begin <= end` and `end <= len` where `len` is the
/// length of the string.
///
/// # Examples
///
/// ```
/// let s = "Löwe 老虎 Léopard";
/// assert_eq!(&s[0 .. 1], "L");
///
/// assert_eq!(&s[1 .. 9], "öwe 老");
///
/// // these will panic:
/// // byte 2 lies within `ö`:
/// // &s[2 ..3];
///
/// // byte 8 lies within `老`
/// // &s[1 .. 8];
///
/// // byte 100 is outside the string
/// // &s[3 .. 100];
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::Range<usize>> for str {
type Output = str;
#[inline]
fn index(&self, index: ops::Range<usize>) -> &str {
index.index(self)
}
}

/// Implements mutable substring slicing with syntax
/// `&mut self[begin .. end]`.
///
/// Returns a mutable slice of the given string from the byte range
/// [`begin`..`end`).
///
/// This operation is `O(1)`.
///
/// # Panics
///
/// Panics if `begin` or `end` does not point to the starting
/// byte offset of a character (as defined by `is_char_boundary`).
/// Requires that `begin <= end` and `end <= len` where `len` is the
/// length of the string.
#[stable(feature = "derefmut_for_string", since = "1.3.0")]
impl ops::IndexMut<ops::Range<usize>> for str {
#[inline]
fn index_mut(&mut self, index: ops::Range<usize>) -> &mut str {
index.index_mut(self)
}
}

/// Implements substring slicing with syntax `&self[.. end]`.
///
/// Returns a slice of the string from the beginning to byte offset
/// `end`.
///
/// Equivalent to `&self[0 .. end]`.
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeTo<usize>> for str {
type Output = str;

#[inline]
fn index(&self, index: ops::RangeTo<usize>) -> &str {
index.index(self)
}
}

/// Implements mutable substring slicing with syntax `&mut self[.. end]`.
///
/// Returns a mutable slice of the string from the beginning to byte offset
/// `end`.
///
/// Equivalent to `&mut self[0 .. end]`.
#[stable(feature = "derefmut_for_string", since = "1.3.0")]
impl ops::IndexMut<ops::RangeTo<usize>> for str {
#[inline]
fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut str {
index.index_mut(self)
}
}

/// Implements substring slicing with syntax `&self[begin ..]`.
///
/// Returns a slice of the string from byte offset `begin`
/// to the end of the string.
///
/// Equivalent to `&self[begin .. len]`.
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeFrom<usize>> for str {
type Output = str;

#[inline]
fn index(&self, index: ops::RangeFrom<usize>) -> &str {
index.index(self)
}
}

/// Implements mutable substring slicing with syntax `&mut self[begin ..]`.
///
/// Returns a mutable slice of the string from byte offset `begin`
/// to the end of the string.
///
/// Equivalent to `&mut self[begin .. len]`.
#[stable(feature = "derefmut_for_string", since = "1.3.0")]
impl ops::IndexMut<ops::RangeFrom<usize>> for str {
#[inline]
fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut str {
index.index_mut(self)
}
}

/// Implements substring slicing with syntax `&self[..]`.
///
/// Returns a slice of the whole string. This operation can
/// never panic.
///
/// Equivalent to `&self[0 .. len]`.
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeFull> for str {
type Output = str;

#[inline]
fn index(&self, _index: ops::RangeFull) -> &str {
self
}
}

/// Implements mutable substring slicing with syntax `&mut self[..]`.
///
/// Returns a mutable slice of the whole string. This operation can
/// never panic.
///
/// Equivalent to `&mut self[0 .. len]`.
#[stable(feature = "derefmut_for_string", since = "1.3.0")]
impl ops::IndexMut<ops::RangeFull> for str {
#[inline]
fn index_mut(&mut self, _index: ops::RangeFull) -> &mut str {
self
}
}

#[stable(feature = "inclusive_range", since = "1.26.0")]
impl ops::Index<ops::RangeInclusive<usize>> for str {
type Output = str;

#[inline]
fn index(&self, index: ops::RangeInclusive<usize>) -> &str {
index.index(self)
}
}

#[stable(feature = "inclusive_range", since = "1.26.0")]
impl ops::Index<ops::RangeToInclusive<usize>> for str {
type Output = str;
#[stable(feature = "str_slice_index", since = "1.32.0")]
impl<T> ops::Index<T> for str
where
T: SliceIndex<str>
{
type Output = T::Output;

#[inline]
fn index(&self, index: ops::RangeToInclusive<usize>) -> &str {
fn index(&self, index: T) -> &T::Output {
index.index(self)
}
}

#[stable(feature = "inclusive_range", since = "1.26.0")]
impl ops::IndexMut<ops::RangeInclusive<usize>> for str {
#[inline]
fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut str {
index.index_mut(self)
}
}
#[stable(feature = "inclusive_range", since = "1.26.0")]
impl ops::IndexMut<ops::RangeToInclusive<usize>> for str {
#[stable(feature = "str_slice_index", since = "1.32.0")]
impl<T> ops::IndexMut<T> for str
where
T: SliceIndex<str>
{
#[inline]
fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut str {
fn index_mut(&mut self, index: T) -> &mut T::Output {
index.index_mut(self)
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/test/ui/index-help.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ error[E0277]: the trait bound `i32: std::slice::SliceIndex<[{integer}]>` is not
--> $DIR/index-help.rs:13:5
|
LL | x[0i32]; //~ ERROR E0277
| ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
| ^^^^^^^ the trait `std::slice::SliceIndex<[{integer}]>` is not implemented for `i32`
|
= help: the trait `std::slice::SliceIndex<[{integer}]>` is not implemented for `i32`
= note: required because of the requirements on the impl of `std::ops::Index<i32>` for `std::vec::Vec<{integer}>`

error: aborting due to previous error
Expand Down
3 changes: 1 addition & 2 deletions src/test/ui/indexing-requires-a-uint.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ error[E0277]: the trait bound `u8: std::slice::SliceIndex<[{integer}]>` is not s
--> $DIR/indexing-requires-a-uint.rs:16:5
|
LL | [0][0u8]; //~ ERROR: the trait bound `u8: std::slice::SliceIndex<[{integer}]>` is not satisfied
| ^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
| ^^^^^^^^ the trait `std::slice::SliceIndex<[{integer}]>` is not implemented for `u8`
|
= help: the trait `std::slice::SliceIndex<[{integer}]>` is not implemented for `u8`
= note: required because of the requirements on the impl of `std::ops::Index<u8>` for `[{integer}]`

error[E0308]: mismatched types
Expand Down
24 changes: 8 additions & 16 deletions src/test/ui/integral-indexing.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,72 +2,64 @@ error[E0277]: the trait bound `u8: std::slice::SliceIndex<[isize]>` is not satis
--> $DIR/integral-indexing.rs:16:5
|
LL | v[3u8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
| ^^^^^^ slice indices are of type `usize` or ranges of `usize`
| ^^^^^^ the trait `std::slice::SliceIndex<[isize]>` is not implemented for `u8`
|
= help: the trait `std::slice::SliceIndex<[isize]>` is not implemented for `u8`
= note: required because of the requirements on the impl of `std::ops::Index<u8>` for `std::vec::Vec<isize>`

error[E0277]: the trait bound `i8: std::slice::SliceIndex<[isize]>` is not satisfied
--> $DIR/integral-indexing.rs:17:5
|
LL | v[3i8]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
| ^^^^^^ slice indices are of type `usize` or ranges of `usize`
| ^^^^^^ the trait `std::slice::SliceIndex<[isize]>` is not implemented for `i8`
|
= help: the trait `std::slice::SliceIndex<[isize]>` is not implemented for `i8`
= note: required because of the requirements on the impl of `std::ops::Index<i8>` for `std::vec::Vec<isize>`

error[E0277]: the trait bound `u32: std::slice::SliceIndex<[isize]>` is not satisfied
--> $DIR/integral-indexing.rs:18:5
|
LL | v[3u32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
| ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
| ^^^^^^^ the trait `std::slice::SliceIndex<[isize]>` is not implemented for `u32`
|
= help: the trait `std::slice::SliceIndex<[isize]>` is not implemented for `u32`
= note: required because of the requirements on the impl of `std::ops::Index<u32>` for `std::vec::Vec<isize>`

error[E0277]: the trait bound `i32: std::slice::SliceIndex<[isize]>` is not satisfied
--> $DIR/integral-indexing.rs:19:5
|
LL | v[3i32]; //~ERROR : std::slice::SliceIndex<[isize]>` is not satisfied
| ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
| ^^^^^^^ the trait `std::slice::SliceIndex<[isize]>` is not implemented for `i32`
|
= help: the trait `std::slice::SliceIndex<[isize]>` is not implemented for `i32`
= note: required because of the requirements on the impl of `std::ops::Index<i32>` for `std::vec::Vec<isize>`

error[E0277]: the trait bound `u8: std::slice::SliceIndex<[u8]>` is not satisfied
--> $DIR/integral-indexing.rs:22:5
|
LL | s.as_bytes()[3u8]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied
| ^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
| ^^^^^^^^^^^^^^^^^ the trait `std::slice::SliceIndex<[u8]>` is not implemented for `u8`
|
= help: the trait `std::slice::SliceIndex<[u8]>` is not implemented for `u8`
= note: required because of the requirements on the impl of `std::ops::Index<u8>` for `[u8]`

error[E0277]: the trait bound `i8: std::slice::SliceIndex<[u8]>` is not satisfied
--> $DIR/integral-indexing.rs:23:5
|
LL | s.as_bytes()[3i8]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied
| ^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
| ^^^^^^^^^^^^^^^^^ the trait `std::slice::SliceIndex<[u8]>` is not implemented for `i8`
|
= help: the trait `std::slice::SliceIndex<[u8]>` is not implemented for `i8`
= note: required because of the requirements on the impl of `std::ops::Index<i8>` for `[u8]`

error[E0277]: the trait bound `u32: std::slice::SliceIndex<[u8]>` is not satisfied
--> $DIR/integral-indexing.rs:24:5
|
LL | s.as_bytes()[3u32]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied
| ^^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
| ^^^^^^^^^^^^^^^^^^ the trait `std::slice::SliceIndex<[u8]>` is not implemented for `u32`
|
= help: the trait `std::slice::SliceIndex<[u8]>` is not implemented for `u32`
= note: required because of the requirements on the impl of `std::ops::Index<u32>` for `[u8]`

error[E0277]: the trait bound `i32: std::slice::SliceIndex<[u8]>` is not satisfied
--> $DIR/integral-indexing.rs:25:5
|
LL | s.as_bytes()[3i32]; //~ERROR : std::slice::SliceIndex<[u8]>` is not satisfied
| ^^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
| ^^^^^^^^^^^^^^^^^^ the trait `std::slice::SliceIndex<[u8]>` is not implemented for `i32`
|
= help: the trait `std::slice::SliceIndex<[u8]>` is not implemented for `i32`
= note: required because of the requirements on the impl of `std::ops::Index<i32>` for `[u8]`

error: aborting due to 8 previous errors
Expand Down
9 changes: 5 additions & 4 deletions src/test/ui/on-unimplemented/slice-index.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ error[E0277]: the trait bound `i32: std::slice::SliceIndex<[i32]>` is not satisf
--> $DIR/slice-index.rs:21:5
|
LL | x[1i32]; //~ ERROR E0277
| ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
| ^^^^^^^ the trait `std::slice::SliceIndex<[i32]>` is not implemented for `i32`
|
= help: the trait `std::slice::SliceIndex<[i32]>` is not implemented for `i32`
= note: required because of the requirements on the impl of `std::ops::Index<i32>` for `[i32]`

error[E0277]: the trait bound `std::ops::RangeTo<i32>: std::slice::SliceIndex<[i32]>` is not satisfied
--> $DIR/slice-index.rs:22:5
|
LL | x[..1i32]; //~ ERROR E0277
| ^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
| ^^^^^^^^^ the trait `std::slice::SliceIndex<[i32]>` is not implemented for `std::ops::RangeTo<i32>`
|
= help: the trait `std::slice::SliceIndex<[i32]>` is not implemented for `std::ops::RangeTo<i32>`
= help: the following implementations were found:
<std::ops::RangeTo<usize> as std::slice::SliceIndex<[T]>>
<std::ops::RangeTo<usize> as std::slice::SliceIndex<str>>
= note: required because of the requirements on the impl of `std::ops::Index<std::ops::RangeTo<i32>>` for `[i32]`

error: aborting due to 2 previous errors
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/str/str-idx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@

pub fn main() {
let s: &str = "hello";
let c: u8 = s[4]; //~ ERROR the type `str` cannot be indexed by `{integer}`
let c: u8 = s[4]; //~ ERROR the trait bound `{integer}: std::slice::SliceIndex<str>`
}
14 changes: 10 additions & 4 deletions src/test/ui/str/str-idx.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
error[E0277]: the type `str` cannot be indexed by `{integer}`
error[E0277]: the trait bound `{integer}: std::slice::SliceIndex<str>` is not satisfied
--> $DIR/str-idx.rs:13:17
|
LL | let c: u8 = s[4]; //~ ERROR the type `str` cannot be indexed by `{integer}`
| ^^^^ `str` cannot be indexed by `{integer}`
LL | let c: u8 = s[4]; //~ ERROR the trait bound `{integer}: std::slice::SliceIndex<str>`
| ^^^^ the trait `std::slice::SliceIndex<str>` is not implemented for `{integer}`
|
= help: the trait `std::ops::Index<{integer}>` is not implemented for `str`
= help: the following implementations were found:
<std::ops::RangeFrom<usize> as std::slice::SliceIndex<[T]>>
<std::ops::RangeFrom<usize> as std::slice::SliceIndex<str>>
<std::ops::RangeTo<usize> as std::slice::SliceIndex<[T]>>
<std::ops::RangeTo<usize> as std::slice::SliceIndex<str>>
and 9 others
= note: required because of the requirements on the impl of `std::ops::Index<{integer}>` for `str`

error: aborting due to previous error

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/str/str-mut-idx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn mutate(s: &mut str) {
//~^ ERROR the size for values of type
//~| ERROR the size for values of type
s[1usize] = bot();
//~^ ERROR the type `str` cannot be mutably indexed by `usize`
//~^ ERROR the trait bound `usize: std::slice::SliceIndex<str>` is not satisfied
}

pub fn main() {}
Loading