Skip to content

Commit 2796048

Browse files
committed
Auto merge of #131721 - okaneco:const_eq_ignore_ascii_case, r=m-ou-se
Add new unstable feature `const_eq_ignore_ascii_case` Tracking issue - #131719 Mark `[u8]`, `str` `eq_ignore_ascii_case` functions const --- The codegen for this implementation matches the existing `iter::zip` implementation better than incrementing with a counter while loop with counter - https://rust.godbolt.org/z/h9cs5zajc while let - https://rust.godbolt.org/z/ecMeMjjEb
2 parents e1fb288 + dedc441 commit 2796048

File tree

3 files changed

+25
-3
lines changed

3 files changed

+25
-3
lines changed

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@
115115
#![feature(const_align_of_val_raw)]
116116
#![feature(const_alloc_layout)]
117117
#![feature(const_black_box)]
118+
#![feature(const_eq_ignore_ascii_case)]
118119
#![feature(const_eval_select)]
119120
#![feature(const_float_methods)]
120121
#![feature(const_heap)]

library/core/src/slice/ascii.rs

+22-2
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,30 @@ impl [u8] {
5252
/// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
5353
/// but without allocating and copying temporaries.
5454
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
55+
#[rustc_const_unstable(feature = "const_eq_ignore_ascii_case", issue = "131719")]
5556
#[must_use]
5657
#[inline]
57-
pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool {
58-
self.len() == other.len() && iter::zip(self, other).all(|(a, b)| a.eq_ignore_ascii_case(b))
58+
pub const fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool {
59+
if self.len() != other.len() {
60+
return false;
61+
}
62+
63+
// FIXME(const-hack): This implementation can be reverted when
64+
// `core::iter::zip` is allowed in const. The original implementation:
65+
// self.len() == other.len() && iter::zip(self, other).all(|(a, b)| a.eq_ignore_ascii_case(b))
66+
let mut a = self;
67+
let mut b = other;
68+
69+
while let ([first_a, rest_a @ ..], [first_b, rest_b @ ..]) = (a, b) {
70+
if first_a.eq_ignore_ascii_case(&first_b) {
71+
a = rest_a;
72+
b = rest_b;
73+
} else {
74+
return false;
75+
}
76+
}
77+
78+
true
5979
}
6080

6181
/// Converts this slice to its ASCII upper case equivalent in-place.

library/core/src/str/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2474,9 +2474,10 @@ impl str {
24742474
/// assert!(!"Ferrös".eq_ignore_ascii_case("FERRÖS"));
24752475
/// ```
24762476
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
2477+
#[rustc_const_unstable(feature = "const_eq_ignore_ascii_case", issue = "131719")]
24772478
#[must_use]
24782479
#[inline]
2479-
pub fn eq_ignore_ascii_case(&self, other: &str) -> bool {
2480+
pub const fn eq_ignore_ascii_case(&self, other: &str) -> bool {
24802481
self.as_bytes().eq_ignore_ascii_case(other.as_bytes())
24812482
}
24822483

0 commit comments

Comments
 (0)