diff options
| author | David Thomas <david2005thomas@gmail.com> | 2024-02-14 17:41:45 +0000 |
|---|---|---|
| committer | GnomedDev <david2005thomas@gmail.com> | 2024-02-18 17:57:12 +0000 |
| commit | 8daf1375437eb381e10fd4a88da5526c7b3ae64b (patch) | |
| tree | 662082de5241daf7e4c928ca66f73489c47d08ce /library/std/src/sys | |
| parent | 8b21296b5db6d5724d6b8440dcf459fa82fd88b5 (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.rs | 23 |
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), |
