about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-06-10 14:03:00 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-06-12 08:47:49 +0000
commit39e7bf6826946bea847b8680e73cbca12c8d9732 (patch)
treee840d38165f687db74b70f4664d5a9f947dd46c2
parent76c73827dcd0b363e60b22c3cef64bde4171bf17 (diff)
downloadrust-39e7bf6826946bea847b8680e73cbca12c8d9732.tar.gz
rust-39e7bf6826946bea847b8680e73cbca12c8d9732.zip
Revert "Rollup merge of #125362 - joboet:tait_hack, r=Nilstrieb"
This reverts commit 1e4bde1cb9736ad4b8d3b95fbfe1533015c1d165, reversing
changes made to 4ee97fc3dbcddc9d69701e346a1be9e0b66855a7.
-rw-r--r--library/core/src/internal_macros.rs41
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/slice/ascii.rs9
-rw-r--r--library/core/src/str/iter.rs6
-rw-r--r--library/core/src/str/mod.rs104
5 files changed, 117 insertions, 44 deletions
diff --git a/library/core/src/internal_macros.rs b/library/core/src/internal_macros.rs
index d3a4d6aff2d..bf53b2245ac 100644
--- a/library/core/src/internal_macros.rs
+++ b/library/core/src/internal_macros.rs
@@ -80,6 +80,47 @@ macro_rules! forward_ref_op_assign {
     }
 }
 
+/// Create a zero-size type similar to a closure type, but named.
+macro_rules! impl_fn_for_zst {
+    ($(
+        $( #[$attr: meta] )*
+        struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn =
+            |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty
+            $body: block;
+    )+) => {
+        $(
+            $( #[$attr] )*
+            struct $Name;
+
+            impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name {
+                #[inline]
+                extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
+                    $body
+                }
+            }
+
+            impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name {
+                #[inline]
+                extern "rust-call" fn call_mut(
+                    &mut self,
+                    ($( $arg, )*): ($( $ArgTy, )*)
+                ) -> $ReturnTy {
+                    Fn::call(&*self, ($( $arg, )*))
+                }
+            }
+
+            impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name {
+                type Output = $ReturnTy;
+
+                #[inline]
+                extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
+                    Fn::call(&self, ($( $arg, )*))
+                }
+            }
+        )+
+    }
+}
+
 /// A macro for defining `#[cfg]` if-else statements.
 ///
 /// `cfg_if` is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 89642d6226a..ef28bc99c4f 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -255,7 +255,6 @@
 #![feature(trait_alias)]
 #![feature(transparent_unions)]
 #![feature(try_blocks)]
-#![feature(type_alias_impl_trait)]
 #![feature(unboxed_closures)]
 #![feature(unsized_fn_params)]
 #![feature(with_negative_coherence)]
diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs
index 19c91ba2eb9..8ad045275ad 100644
--- a/library/core/src/slice/ascii.rs
+++ b/library/core/src/slice/ascii.rs
@@ -108,7 +108,7 @@ impl [u8] {
                   without modifying the original"]
     #[stable(feature = "inherent_ascii_escape", since = "1.60.0")]
     pub fn escape_ascii(&self) -> EscapeAscii<'_> {
-        EscapeAscii { inner: self.iter().flat_map(|byte| byte.escape_ascii()) }
+        EscapeAscii { inner: self.iter().flat_map(EscapeByte) }
     }
 
     /// Returns a byte slice with leading ASCII whitespace bytes removed.
@@ -190,7 +190,12 @@ impl [u8] {
     }
 }
 
-type EscapeByte = impl (Fn(&u8) -> ascii::EscapeDefault) + Copy;
+impl_fn_for_zst! {
+    #[derive(Clone)]
+    struct EscapeByte impl Fn = |byte: &u8| -> ascii::EscapeDefault {
+        ascii::escape_default(*byte)
+    };
+}
 
 /// An iterator over the escaped version of a byte slice.
 ///
diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs
index d61f04102e5..19627f28e64 100644
--- a/library/core/src/str/iter.rs
+++ b/library/core/src/str/iter.rs
@@ -1274,10 +1274,8 @@ pub struct SplitWhitespace<'a> {
 #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
 #[derive(Clone, Debug)]
 pub struct SplitAsciiWhitespace<'a> {
-    pub(super) inner: Map<
-        Filter<SliceSplit<'a, u8, IsAsciiWhitespace>, BytesIsNotEmpty<'a>>,
-        UnsafeBytesToStr<'a>,
-    >,
+    pub(super) inner:
+        Map<Filter<SliceSplit<'a, u8, IsAsciiWhitespace>, BytesIsNotEmpty>, UnsafeBytesToStr>,
 }
 
 /// An iterator over the substrings of a string,
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index edda4d1b687..669cdc92e35 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -983,7 +983,7 @@ impl str {
     #[cfg_attr(not(test), rustc_diagnostic_item = "str_split_whitespace")]
     #[inline]
     pub fn split_whitespace(&self) -> SplitWhitespace<'_> {
-        SplitWhitespace { inner: self.split(char::is_whitespace).filter(|s| !s.is_empty()) }
+        SplitWhitespace { inner: self.split(IsWhitespace).filter(IsNotEmpty) }
     }
 
     /// Splits a string slice by ASCII whitespace.
@@ -1032,13 +1032,8 @@ impl str {
     #[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
     #[inline]
     pub fn split_ascii_whitespace(&self) -> SplitAsciiWhitespace<'_> {
-        let inner = self
-            .as_bytes()
-            .split(u8::is_ascii_whitespace)
-            .filter(|s| !s.is_empty())
-            // SAFETY: the byte slice came from a string and was only split
-            // along character boundaries, so the resulting slices are strings.
-            .map(|bytes| unsafe { from_utf8_unchecked(bytes) });
+        let inner =
+            self.as_bytes().split(IsAsciiWhitespace).filter(BytesIsNotEmpty).map(UnsafeBytesToStr);
         SplitAsciiWhitespace { inner }
     }
 
@@ -1090,11 +1085,7 @@ impl str {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn lines(&self) -> Lines<'_> {
-        Lines(self.split_inclusive('\n').map(|line| {
-            let Some(line) = line.strip_suffix('\n') else { return line };
-            let Some(line) = line.strip_suffix('\r') else { return line };
-            line
-        }))
+        Lines(self.split_inclusive('\n').map(LinesMap))
     }
 
     /// An iterator over the lines of a string.
@@ -2645,19 +2636,14 @@ impl str {
     #[stable(feature = "str_escape", since = "1.34.0")]
     pub fn escape_debug(&self) -> EscapeDebug<'_> {
         let mut chars = self.chars();
-        let first = chars
-            .next()
-            .map(|first| first.escape_debug_ext(EscapeDebugExtArgs::ESCAPE_ALL))
-            .into_iter()
-            .flatten();
-        let inner = first.chain(chars.flat_map(|c| {
-            c.escape_debug_ext(EscapeDebugExtArgs {
-                escape_grapheme_extended: false,
-                escape_single_quote: true,
-                escape_double_quote: true,
-            })
-        }));
-        EscapeDebug { inner }
+        EscapeDebug {
+            inner: chars
+                .next()
+                .map(|first| first.escape_debug_ext(EscapeDebugExtArgs::ESCAPE_ALL))
+                .into_iter()
+                .flatten()
+                .chain(chars.flat_map(CharEscapeDebugContinue)),
+        }
     }
 
     /// Return an iterator that escapes each char in `self` with [`char::escape_default`].
@@ -2695,7 +2681,7 @@ impl str {
                   without modifying the original"]
     #[stable(feature = "str_escape", since = "1.34.0")]
     pub fn escape_default(&self) -> EscapeDefault<'_> {
-        EscapeDefault { inner: self.chars().flat_map(char::escape_default) }
+        EscapeDefault { inner: self.chars().flat_map(CharEscapeDefault) }
     }
 
     /// Return an iterator that escapes each char in `self` with [`char::escape_unicode`].
@@ -2733,7 +2719,7 @@ impl str {
                   without modifying the original"]
     #[stable(feature = "str_escape", since = "1.34.0")]
     pub fn escape_unicode(&self) -> EscapeUnicode<'_> {
-        EscapeUnicode { inner: self.chars().flat_map(char::escape_unicode) }
+        EscapeUnicode { inner: self.chars().flat_map(CharEscapeUnicode) }
     }
 }
 
@@ -2764,15 +2750,59 @@ impl Default for &mut str {
     }
 }
 
-type LinesMap = impl (Fn(&str) -> &str) + Copy;
-type CharEscapeDebugContinue = impl (FnMut(char) -> char::EscapeDebug) + Copy;
-type CharEscapeUnicode = impl (Fn(char) -> char::EscapeUnicode) + Copy;
-type CharEscapeDefault = impl (Fn(char) -> char::EscapeDefault) + Copy;
-type IsWhitespace = impl (Fn(char) -> bool) + Copy;
-type IsAsciiWhitespace = impl (Fn(&u8) -> bool) + Copy;
-type IsNotEmpty = impl (Fn(&&str) -> bool) + Copy;
-type BytesIsNotEmpty<'a> = impl (FnMut(&&'a [u8]) -> bool) + Copy;
-type UnsafeBytesToStr<'a> = impl (FnMut(&'a [u8]) -> &'a str) + Copy;
+impl_fn_for_zst! {
+    /// A nameable, cloneable fn type
+    #[derive(Clone)]
+    struct LinesMap impl<'a> Fn = |line: &'a str| -> &'a str {
+        let Some(line) = line.strip_suffix('\n') else { return line };
+        let Some(line) = line.strip_suffix('\r') else { return line };
+        line
+    };
+
+    #[derive(Clone)]
+    struct CharEscapeDebugContinue impl Fn = |c: char| -> char::EscapeDebug {
+        c.escape_debug_ext(EscapeDebugExtArgs {
+            escape_grapheme_extended: false,
+            escape_single_quote: true,
+            escape_double_quote: true
+        })
+    };
+
+    #[derive(Clone)]
+    struct CharEscapeUnicode impl Fn = |c: char| -> char::EscapeUnicode {
+        c.escape_unicode()
+    };
+    #[derive(Clone)]
+    struct CharEscapeDefault impl Fn = |c: char| -> char::EscapeDefault {
+        c.escape_default()
+    };
+
+    #[derive(Clone)]
+    struct IsWhitespace impl Fn = |c: char| -> bool {
+        c.is_whitespace()
+    };
+
+    #[derive(Clone)]
+    struct IsAsciiWhitespace impl Fn = |byte: &u8| -> bool {
+        byte.is_ascii_whitespace()
+    };
+
+    #[derive(Clone)]
+    struct IsNotEmpty impl<'a, 'b> Fn = |s: &'a &'b str| -> bool {
+        !s.is_empty()
+    };
+
+    #[derive(Clone)]
+    struct BytesIsNotEmpty impl<'a, 'b> Fn = |s: &'a &'b [u8]| -> bool {
+        !s.is_empty()
+    };
+
+    #[derive(Clone)]
+    struct UnsafeBytesToStr impl<'a> Fn = |bytes: &'a [u8]| -> &'a str {
+        // SAFETY: not safe
+        unsafe { from_utf8_unchecked(bytes) }
+    };
+}
 
 // This is required to make `impl From<&str> for Box<dyn Error>` and `impl<E> From<E> for Box<dyn Error>` not overlap.
 #[stable(feature = "rust1", since = "1.0.0")]