diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-01-22 12:20:28 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-01-22 12:20:28 +0100 |
| commit | ad55b73da1e3701cf09c54dc813779adbae39d5b (patch) | |
| tree | a9cdbdfa329555f0c355dc9d2ee8d060dfe121e9 /src/libcore | |
| parent | e3d3cff019248a92a6c759417dae253cc32dabaf (diff) | |
| parent | c7d25a2a4082e6d2601ea4c06ea01b632d196172 (diff) | |
| download | rust-ad55b73da1e3701cf09c54dc813779adbae39d5b.tar.gz rust-ad55b73da1e3701cf09c54dc813779adbae39d5b.zip | |
Rollup merge of #57604 - alercah:str-index, r=sfackler
Make `str` indexing generic on `SliceIndex`. Fixes #55603
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/ops/index.rs | 15 | ||||
| -rw-r--r-- | src/libcore/slice/mod.rs | 16 | ||||
| -rw-r--r-- | src/libcore/str/mod.rs | 296 |
3 files changed, 132 insertions, 195 deletions
diff --git a/src/libcore/ops/index.rs b/src/libcore/ops/index.rs index 6cfa36741d0..d4ed8614276 100644 --- a/src/libcore/ops/index.rs +++ b/src/libcore/ops/index.rs @@ -51,21 +51,6 @@ /// ``` #[lang = "index"] #[rustc_on_unimplemented( - on( - _Self="&str", - note="you can use `.chars().nth()` or `.bytes().nth()` -see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>" - ), - on( - _Self="str", - note="you can use `.chars().nth()` or `.bytes().nth()` -see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>" - ), - on( - _Self="std::string::String", - note="you can use `.chars().nth()` or `.bytes().nth()` -see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>" - ), message="the type `{Self}` cannot be indexed by `{Idx}`", label="`{Self}` cannot be indexed by `{Idx}`", )] diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index df4d97ee6a4..9f9515e6d9b 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -2383,7 +2383,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]> { @@ -2396,7 +2395,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]> { @@ -2447,7 +2445,19 @@ 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`"] +#[rustc_on_unimplemented( + on( + T = "str", + label = "string indices are ranges of `usize`", + ), + on( + all(any(T = "str", T = "&str", T = "std::string::String"), _Self="{integer}"), + note="you can use `.chars().nth()` or `.bytes().nth()` +see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>" + ), + message = "the type `{T}` cannot be indexed by `{Self}`", + label = "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")] diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index bdde187d931..1ee8b7735c1 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1621,190 +1621,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; + impl<I> ops::Index<I> for str + where + I: SliceIndex<str>, + { + type Output = I::Output; #[inline] - fn index(&self, index: ops::RangeFrom<usize>) -> &str { + fn index(&self, index: I) -> &I::Output { 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; - - #[inline] - fn index(&self, index: ops::RangeToInclusive<usize>) -> &str { - 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 { + impl<I> ops::IndexMut<I> for str + where + I: SliceIndex<str>, + { #[inline] - fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut str { + fn index_mut(&mut self, index: I) -> &mut I::Output { index.index_mut(self) } } @@ -1815,6 +1651,18 @@ mod traits { panic!("attempted to index str up to maximum usize"); } + /// Implements substring slicing with syntax `&self[..]` or `&mut self[..]`. + /// + /// Returns a slice of the whole string, i.e., returns `&self` or `&mut + /// self`. Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. Unlike + /// other indexing operations, this can never panic. + /// + /// This operation is `O(1)`. + /// + /// Prior to 1.20.0, these indexing operations were still supported by + /// direct implementation of `Index` and `IndexMut`. + /// + /// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] impl SliceIndex<str> for ops::RangeFull { type Output = str; @@ -1844,6 +1692,41 @@ mod traits { } } + /// Implements substring slicing with syntax `&self[begin .. end]` or `&mut + /// self[begin .. end]`. + /// + /// Returns a slice of the given string from the byte range + /// [`begin`, `end`). + /// + /// This operation is `O(1)`. + /// + /// Prior to 1.20.0, these indexing operations were still supported by + /// direct implementation of `Index` and `IndexMut`. + /// + /// # Panics + /// + /// Panics if `begin` or `end` does not point to the starting byte offset of + /// a character (as defined by `is_char_boundary`), if `begin > end`, or if + /// `end > len`. + /// + /// # 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 = "str_checked_slicing", since = "1.20.0")] impl SliceIndex<str> for ops::Range<usize> { type Output = str; @@ -1898,6 +1781,21 @@ mod traits { } } + /// Implements substring slicing with syntax `&self[.. end]` or `&mut + /// self[.. end]`. + /// + /// Returns a slice of the given string from the byte range [`0`, `end`). + /// Equivalent to `&self[0 .. end]` or `&mut self[0 .. end]`. + /// + /// This operation is `O(1)`. + /// + /// Prior to 1.20.0, these indexing operations were still supported by + /// direct implementation of `Index` and `IndexMut`. + /// + /// # Panics + /// + /// Panics if `end` does not point to the starting byte offset of a + /// character (as defined by `is_char_boundary`), or if `end > len`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] impl SliceIndex<str> for ops::RangeTo<usize> { type Output = str; @@ -1943,6 +1841,22 @@ mod traits { } } + /// Implements substring slicing with syntax `&self[begin ..]` or `&mut + /// self[begin ..]`. + /// + /// Returns a slice of the given string from the byte range [`begin`, + /// `len`). Equivalent to `&self[begin .. len]` or `&mut self[begin .. + /// len]`. + /// + /// This operation is `O(1)`. + /// + /// Prior to 1.20.0, these indexing operations were still supported by + /// direct implementation of `Index` and `IndexMut`. + /// + /// # Panics + /// + /// Panics if `begin` does not point to the starting byte offset of + /// a character (as defined by `is_char_boundary`), or if `begin >= len`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] impl SliceIndex<str> for ops::RangeFrom<usize> { type Output = str; @@ -1990,6 +1904,22 @@ mod traits { } } + /// Implements substring slicing with syntax `&self[begin ..= end]` or `&mut + /// self[begin ..= end]`. + /// + /// Returns a slice of the given string from the byte range + /// [`begin`, `end`]. Equivalent to `&self [begin .. end + 1]` or `&mut + /// self[begin .. end + 1]`, except if `end` has the maximum value for + /// `usize`. + /// + /// This operation is `O(1)`. + /// + /// # Panics + /// + /// Panics if `begin` does not point to the starting byte offset of + /// a character (as defined by `is_char_boundary`), if `end` does not point + /// to the ending byte offset of a character (`end + 1` is either a starting + /// byte offset or equal to `len`), if `begin > end`, or if `end >= len`. #[stable(feature = "inclusive_range", since = "1.26.0")] impl SliceIndex<str> for ops::RangeInclusive<usize> { type Output = str; @@ -2023,8 +1953,20 @@ mod traits { } } - - + /// Implements substring slicing with syntax `&self[..= end]` or `&mut + /// self[..= end]`. + /// + /// Returns a slice of the given string from the byte range [0, `end`]. + /// Equivalent to `&self [0 .. end + 1]`, except if `end` has the maximum + /// value for `usize`. + /// + /// This operation is `O(1)`. + /// + /// # Panics + /// + /// Panics if `end` does not point to the ending byte offset of a character + /// (`end + 1` is either a starting byte offset as defined by + /// `is_char_boundary`, or equal to `len`), or if `end >= len`. #[stable(feature = "inclusive_range", since = "1.26.0")] impl SliceIndex<str> for ops::RangeToInclusive<usize> { type Output = str; |
