about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-08-31 16:19:09 +0000
committerbors <bors@rust-lang.org>2025-08-31 16:19:09 +0000
commitf73bcd50a433b7c17225ca98b44064236e7e84b3 (patch)
tree68ac0af462fd9571d2d417d2f4b1abf2924a09c8
parent564ee219127b796d56f74767366fd359758b97de (diff)
parent6d8d952e48689065931566209b5c992434fe0e82 (diff)
downloadrust-f73bcd50a433b7c17225ca98b44064236e7e84b3.tar.gz
rust-f73bcd50a433b7c17225ca98b44064236e7e84b3.zip
Auto merge of #146053 - joboet:split-paths-regression, r=Mark-Simulacrum
std: fix `SplitPaths` regression

Fixes rust-lang/rust#146045 by defining the TAIT more precisely, ensuring that `'a` does not need to be live on drop.
-rw-r--r--library/std/src/sys/pal/unix/os.rs20
-rw-r--r--tests/ui/type-alias-impl-trait/split-paths-may-dangle.rs11
2 files changed, 26 insertions, 5 deletions
diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs
index aec089f7e5c..f0b6068e06c 100644
--- a/library/std/src/sys/pal/unix/os.rs
+++ b/library/std/src/sys/pal/unix/os.rs
@@ -186,14 +186,24 @@ pub fn chdir(p: &path::Path) -> io::Result<()> {
     if result == 0 { Ok(()) } else { Err(io::Error::last_os_error()) }
 }
 
-pub type SplitPaths<'a> = impl Iterator<Item = PathBuf>;
+// This can't just be `impl Iterator` because that requires `'a` to be live on
+// drop (see #146045).
+pub type SplitPaths<'a> = iter::Map<
+    slice::Split<'a, u8, impl FnMut(&u8) -> bool + 'static>,
+    impl FnMut(&[u8]) -> PathBuf + 'static,
+>;
 
 #[define_opaque(SplitPaths)]
 pub fn split_paths(unparsed: &OsStr) -> SplitPaths<'_> {
-    unparsed
-        .as_bytes()
-        .split(|&b| b == PATH_SEPARATOR)
-        .map(|part| PathBuf::from(OsStr::from_bytes(part)))
+    fn is_separator(&b: &u8) -> bool {
+        b == PATH_SEPARATOR
+    }
+
+    fn into_pathbuf(part: &[u8]) -> PathBuf {
+        PathBuf::from(OsStr::from_bytes(part))
+    }
+
+    unparsed.as_bytes().split(is_separator).map(into_pathbuf)
 }
 
 #[derive(Debug)]
diff --git a/tests/ui/type-alias-impl-trait/split-paths-may-dangle.rs b/tests/ui/type-alias-impl-trait/split-paths-may-dangle.rs
new file mode 100644
index 00000000000..61c5342cdbb
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/split-paths-may-dangle.rs
@@ -0,0 +1,11 @@
+// Regression test for issue #146045 - ensure that the TAIT `SplitPaths` does not
+// require the borrowed string to be live.
+//@ check-pass
+//@ edition:2015
+
+pub fn repro() -> Option<std::path::PathBuf> {
+    let unparsed = std::ffi::OsString::new();
+    std::env::split_paths(&unparsed).next()
+}
+
+fn main() {}