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.

``