about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/slice/ascii.rs24
-rw-r--r--library/core/src/str/mod.rs3
3 files changed, 25 insertions, 3 deletions
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 87c6bb39ce6..2f4f33dcc85 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -115,6 +115,7 @@
 #![feature(const_align_of_val_raw)]
 #![feature(const_alloc_layout)]
 #![feature(const_black_box)]
+#![feature(const_eq_ignore_ascii_case)]
 #![feature(const_eval_select)]
 #![feature(const_float_methods)]
 #![feature(const_heap)]
diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs
index 58ba3a1573a..17ad4fd8f67 100644
--- a/library/core/src/slice/ascii.rs
+++ b/library/core/src/slice/ascii.rs
@@ -52,10 +52,30 @@ impl [u8] {
     /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
     /// but without allocating and copying temporaries.
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
+    #[rustc_const_unstable(feature = "const_eq_ignore_ascii_case", issue = "131719")]
     #[must_use]
     #[inline]
-    pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool {
-        self.len() == other.len() && iter::zip(self, other).all(|(a, b)| a.eq_ignore_ascii_case(b))
+    pub const fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool {
+        if self.len() != other.len() {
+            return false;
+        }
+
+        // FIXME(const-hack): This implementation can be reverted when
+        // `core::iter::zip` is allowed in const. The original implementation:
+        //  self.len() == other.len() && iter::zip(self, other).all(|(a, b)| a.eq_ignore_ascii_case(b))
+        let mut a = self;
+        let mut b = other;
+
+        while let ([first_a, rest_a @ ..], [first_b, rest_b @ ..]) = (a, b) {
+            if first_a.eq_ignore_ascii_case(&first_b) {
+                a = rest_a;
+                b = rest_b;
+            } else {
+                return false;
+            }
+        }
+
+        true
     }
 
     /// Converts this slice to its ASCII upper case equivalent in-place.
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 58d6e07de8d..0f7c2c999d0 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -2474,9 +2474,10 @@ impl str {
     /// assert!(!"Ferrös".eq_ignore_ascii_case("FERRÖS"));
     /// ```
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
+    #[rustc_const_unstable(feature = "const_eq_ignore_ascii_case", issue = "131719")]
     #[must_use]
     #[inline]
-    pub fn eq_ignore_ascii_case(&self, other: &str) -> bool {
+    pub const fn eq_ignore_ascii_case(&self, other: &str) -> bool {
         self.as_bytes().eq_ignore_ascii_case(other.as_bytes())
     }