about summary refs log tree commit diff
path: root/library/std/src/sys
diff options
context:
space:
mode:
authorDavid Thomas <david2005thomas@gmail.com>2024-02-14 17:41:45 +0000
committerGnomedDev <david2005thomas@gmail.com>2024-02-18 17:57:12 +0000
commit8daf1375437eb381e10fd4a88da5526c7b3ae64b (patch)
tree662082de5241daf7e4c928ca66f73489c47d08ce /library/std/src/sys
parent8b21296b5db6d5724d6b8440dcf459fa82fd88b5 (diff)
Reduce monomorphisation bloat in small_c_string
Diffstat (limited to 'library/std/src/sys')
-rw-r--r--library/std/src/sys/pal/common/small_c_string.rs23
1 files changed, 15 insertions, 8 deletions
diff --git a/library/std/src/sys/pal/common/small_c_string.rs b/library/std/src/sys/pal/common/small_c_string.rs
index af9b18e372d..2312e6e5ee2 100644
--- a/library/std/src/sys/pal/common/small_c_string.rs
+++ b/library/std/src/sys/pal/common/small_c_string.rs
@@ -17,20 +17,27 @@ const NUL_ERR: io::Error =
 #[inline]
 pub fn run_path_with_cstr<T, F>(path: &Path, f: F) -> io::Result<T>
 where
-    F: FnOnce(&CStr) -> io::Result<T>,
+    F: FnMut(&CStr) -> io::Result<T>,
 {
     run_with_cstr(path.as_os_str().as_encoded_bytes(), f)
 }
 
 #[inline]
-pub fn run_with_cstr<T, F>(bytes: &[u8], f: F) -> io::Result<T>
+pub fn run_with_cstr<T, F>(bytes: &[u8], mut f: F) -> io::Result<T>
 where
-    F: FnOnce(&CStr) -> io::Result<T>,
+    F: FnMut(&CStr) -> io::Result<T>,
 {
     if bytes.len() >= MAX_STACK_ALLOCATION {
-        return run_with_cstr_allocating(bytes, f);
+        run_with_cstr_allocating(bytes, &mut f)
+    } else {
+        unsafe { run_with_cstr_stack(bytes, &mut f) }
     }
+}
 
+unsafe fn run_with_cstr_stack<T>(
+    bytes: &[u8],
+    f: &mut dyn FnMut(&CStr) -> io::Result<T>,
+) -> io::Result<T> {
     let mut buf = MaybeUninit::<[u8; MAX_STACK_ALLOCATION]>::uninit();
     let buf_ptr = buf.as_mut_ptr() as *mut u8;
 
@@ -47,10 +54,10 @@ where
 
 #[cold]
 #[inline(never)]
-fn run_with_cstr_allocating<T, F>(bytes: &[u8], f: F) -> io::Result<T>
-where
-    F: FnOnce(&CStr) -> io::Result<T>,
-{
+fn run_with_cstr_allocating<T>(
+    bytes: &[u8],
+    f: &mut dyn FnMut(&CStr) -> io::Result<T>,
+) -> io::Result<T> {
     match CString::new(bytes) {
         Ok(s) => f(&s),
         Err(_) => Err(NUL_ERR),