@@ -185,30 +185,49 @@ 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 = "none" ) ]
188
189
#[ inline]
189
- pub fn is_char_boundary ( & self , index : usize ) -> bool {
190
- // 0 is always ok.
191
- // Test for 0 explicitly so that it can optimize out the check
192
- // easily and skip reading string data for that case.
193
- // Note that optimizing `self.get(..index)` relies on this.
194
- if index == 0 {
195
- return true ;
190
+ pub const fn is_char_boundary ( & self , index : usize ) -> bool {
191
+ fn is_char_boundary_runtime ( s : & str , index : usize ) -> bool {
192
+ // 0 is always ok.
193
+ // Test for 0 explicitly so that it can optimize out the check
194
+ // easily and skip reading string data for that case.
195
+ // Note that optimizing `self.get(..index)` relies on this.
196
+ if index == 0 {
197
+ return true ;
198
+ }
199
+
200
+ match s. as_bytes ( ) . get ( index) {
201
+ // For `None` we have two options:
202
+ //
203
+ // - index == self.len()
204
+ // Empty strings are valid, so return true
205
+ // - index > self.len()
206
+ // In this case return false
207
+ //
208
+ // The check is placed exactly here, because it improves generated
209
+ // code on higher opt-levels. See PR #84751 for more details.
210
+ None => index == s. len ( ) ,
211
+
212
+ Some ( & b) => b. is_utf8_char_boundary ( ) ,
213
+ }
196
214
}
197
-
198
- match self . as_bytes ( ) . get ( index) {
199
- // For `None` we have two options:
200
- //
201
- // - index == self.len()
202
- // Empty strings are valid, so return true
203
- // - index > self.len()
204
- // In this case return false
205
- //
206
- // The check is placed exactly here, because it improves generated
207
- // 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 ( ) ,
215
+ const fn is_char_boundary_const ( s : & str , index : usize ) -> bool {
216
+ // 0 is always ok, s.len() is always okay
217
+ if index == 0 || index == s. len ( ) {
218
+ true
219
+ } else if index > s. len ( ) {
220
+ false
221
+ } else {
222
+ // now we know index is a valid byte index in s
223
+ s. as_bytes ( ) [ index] . is_utf8_char_boundary ( )
224
+ }
211
225
}
226
+ crate :: intrinsics:: const_eval_select (
227
+ ( self , index) ,
228
+ is_char_boundary_const,
229
+ is_char_boundary_runtime,
230
+ )
212
231
}
213
232
214
233
/// Finds the closest `x` not exceeding `index` where `is_char_boundary(x)` is `true`.
0 commit comments