Rollup merge of #131520 - zachs18:const-str-split, r=Noratrieb · qinheping/verify-rust-std@d0a99e7 (original) (raw)
`@@ -185,8 +185,9 @@ impl str {
`
185
185
```` /// ```
````
186
186
`#[must_use]
`
187
187
`#[stable(feature = "is_char_boundary", since = "1.9.0")]
`
``
188
`+
#[rustc_const_unstable(feature = "const_is_char_boundary", issue = "131516")]
`
188
189
`#[inline]
`
189
``
`-
pub fn is_char_boundary(&self, index: usize) -> bool {
`
``
190
`+
pub const fn is_char_boundary(&self, index: usize) -> bool {
`
190
191
`// 0 is always ok.
`
191
192
`// Test for 0 explicitly so that it can optimize out the check
`
192
193
`// easily and skip reading string data for that case.
`
`@@ -195,8 +196,8 @@ impl str {
`
195
196
`return true;
`
196
197
`}
`
197
198
``
198
``
`-
match self.as_bytes().get(index) {
`
199
``
`` -
// For None
we have two options:
``
``
199
`+
if index >= self.len() {
`
``
200
`` +
// For true
we have two options:
``
200
201
`//
`
201
202
`// - index == self.len()
`
202
203
`// Empty strings are valid, so return true
`
`@@ -205,9 +206,9 @@ impl str {
`
205
206
`//
`
206
207
`// The check is placed exactly here, because it improves generated
`
207
208
`// code on higher opt-levels. See PR #84751 for more details.
`
208
``
`-
None => index == self.len(),
`
209
``
-
210
``
`-
Some(&b) => b.is_utf8_char_boundary(),
`
``
209
`+
index == self.len()
`
``
210
`+
} else {
`
``
211
`+
self.as_bytes()[index].is_utf8_char_boundary()
`
211
212
`}
`
212
213
`}
`
213
214
``
`@@ -637,7 +638,8 @@ impl str {
`
637
638
`#[inline]
`
638
639
`#[must_use]
`
639
640
`#[stable(feature = "str_split_at", since = "1.4.0")]
`
640
``
`-
pub fn split_at(&self, mid: usize) -> (&str, &str) {
`
``
641
`+
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
`
``
642
`+
pub const fn split_at(&self, mid: usize) -> (&str, &str) {
`
641
643
`match self.split_at_checked(mid) {
`
642
644
`None => slice_error_fail(self, 0, mid),
`
643
645
`Some(pair) => pair,
`
`@@ -677,7 +679,8 @@ impl str {
`
677
679
`#[inline]
`
678
680
`#[must_use]
`
679
681
`#[stable(feature = "str_split_at", since = "1.4.0")]
`
680
``
`-
pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
`
``
682
`+
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
`
``
683
`+
pub const fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
`
681
684
`// is_char_boundary checks that the index is in [0, .len()]
`
682
685
`if self.is_char_boundary(mid) {
`
683
686
`` // SAFETY: just checked that mid
is on a char boundary.
``
`@@ -716,11 +719,12 @@ impl str {
`
716
719
`#[inline]
`
717
720
`#[must_use]
`
718
721
`#[stable(feature = "split_at_checked", since = "1.80.0")]
`
719
``
`-
pub fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
`
``
722
`+
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
`
``
723
`+
pub const fn split_at_checked(&self, mid: usize) -> Option<(&str, &str)> {
`
720
724
`// is_char_boundary checks that the index is in [0, .len()]
`
721
725
`if self.is_char_boundary(mid) {
`
722
726
`` // SAFETY: just checked that mid
is on a char boundary.
``
723
``
`-
Some(unsafe { (self.get_unchecked(0..mid), self.get_unchecked(mid..self.len())) })
`
``
727
`+
Some(unsafe { self.split_at_unchecked(mid) })
`
724
728
`} else {
`
725
729
`None
`
726
730
`}
`
`@@ -756,7 +760,9 @@ impl str {
`
756
760
`#[inline]
`
757
761
`#[must_use]
`
758
762
`#[stable(feature = "split_at_checked", since = "1.80.0")]
`
759
``
`-
pub fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> {
`
``
763
`+
#[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
`
``
764
`+
#[rustc_allow_const_fn_unstable(const_is_char_boundary)]
`
``
765
`+
pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> {
`
760
766
`// is_char_boundary checks that the index is in [0, .len()]
`
761
767
`if self.is_char_boundary(mid) {
`
762
768
`` // SAFETY: just checked that mid
is on a char boundary.
``
`@@ -772,7 +778,25 @@ impl str {
`
772
778
`///
`
773
779
`` /// The caller must ensure that mid
is a valid byte offset from the start
``
774
780
`/// of the string and falls on the boundary of a UTF-8 code point.
`
775
``
`-
unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut str, &mut str) {
`
``
781
`+
const unsafe fn split_at_unchecked(&self, mid: usize) -> (&str, &str) {
`
``
782
`+
let len = self.len();
`
``
783
`+
let ptr = self.as_ptr();
`
``
784
`` +
// SAFETY: caller guarantees mid
is on a char boundary.
``
``
785
`+
unsafe {
`
``
786
`+
(
`
``
787
`+
from_utf8_unchecked(slice::from_raw_parts(ptr, mid)),
`
``
788
`+
from_utf8_unchecked(slice::from_raw_parts(ptr.add(mid), len - mid)),
`
``
789
`+
)
`
``
790
`+
}
`
``
791
`+
}
`
``
792
+
``
793
`+
/// Divides one string slice into two at an index.
`
``
794
`+
///
`
``
795
`+
/// # Safety
`
``
796
`+
///
`
``
797
`` +
/// The caller must ensure that mid
is a valid byte offset from the start
``
``
798
`+
/// of the string and falls on the boundary of a UTF-8 code point.
`
``
799
`+
const unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut str, &mut str) {
`
776
800
`let len = self.len();
`
777
801
`let ptr = self.as_mut_ptr();
`
778
802
`` // SAFETY: caller guarantees mid
is on a char boundary.
``