diff options
Diffstat (limited to 'library/std/src')
48 files changed, 260 insertions, 140 deletions
diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index 5d2a304b41c..75971ac90e7 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -348,7 +348,7 @@ fn default_alloc_error_hook(layout: Layout) { unsafe extern "Rust" { // This symbol is emitted by rustc next to __rust_alloc_error_handler. // Its value depends on the -Zoom={panic,abort} compiler option. - #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)] + #[rustc_std_internal_symbol] static __rust_alloc_error_handler_should_panic: u8; } diff --git a/library/std/src/backtrace.rs b/library/std/src/backtrace.rs index 3e641ac5d90..3683485640c 100644 --- a/library/std/src/backtrace.rs +++ b/library/std/src/backtrace.rs @@ -432,7 +432,7 @@ mod helper { use super::*; pub(super) type LazyResolve = impl (FnOnce() -> Capture) + Send + Sync + UnwindSafe; - #[cfg_attr(not(bootstrap), define_opaque(LazyResolve))] + #[define_opaque(LazyResolve)] pub(super) fn lazy_resolve(mut capture: Capture) -> LazyResolve { move || { // Use the global backtrace lock to synchronize this as it's a diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 2487f5a2a50..0eef2bd225c 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -683,7 +683,7 @@ impl<K, V, S> HashMap<K, V, S> { /// ``` #[inline] #[rustc_lint_query_instability] - #[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "hash_extract_if", since = "1.87.0")] pub fn extract_if<F>(&mut self, pred: F) -> ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool, @@ -1677,7 +1677,7 @@ impl<'a, K, V> Drain<'a, K, V> { /// ]); /// let iter = map.extract_if(|_k, v| *v % 2 == 0); /// ``` -#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "hash_extract_if", since = "1.87.0")] #[must_use = "iterators are lazy and do nothing unless consumed"] pub struct ExtractIf<'a, K, V, F> where @@ -2294,7 +2294,7 @@ where } } -#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "hash_extract_if", since = "1.87.0")] impl<K, V, F> Iterator for ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool, @@ -2311,10 +2311,10 @@ where } } -#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "hash_extract_if", since = "1.87.0")] impl<K, V, F> FusedIterator for ExtractIf<'_, K, V, F> where F: FnMut(&K, &mut V) -> bool {} -#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "hash_extract_if", since = "1.87.0")] impl<'a, K, V, F> fmt::Debug for ExtractIf<'a, K, V, F> where F: FnMut(&K, &mut V) -> bool, diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index a547a9943c1..7be000594bc 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -308,7 +308,7 @@ impl<T, S> HashSet<T, S> { /// ``` #[inline] #[rustc_lint_query_instability] - #[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "hash_extract_if", since = "1.87.0")] pub fn extract_if<F>(&mut self, pred: F) -> ExtractIf<'_, T, F> where F: FnMut(&T) -> bool, @@ -1390,7 +1390,7 @@ pub struct Drain<'a, K: 'a> { /// /// let mut extract_ifed = a.extract_if(|v| v % 2 == 0); /// ``` -#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "hash_extract_if", since = "1.87.0")] pub struct ExtractIf<'a, K, F> where F: FnMut(&K) -> bool, @@ -1673,7 +1673,7 @@ impl<K: fmt::Debug> fmt::Debug for Drain<'_, K> { } } -#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "hash_extract_if", since = "1.87.0")] impl<K, F> Iterator for ExtractIf<'_, K, F> where F: FnMut(&K) -> bool, @@ -1690,10 +1690,10 @@ where } } -#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "hash_extract_if", since = "1.87.0")] impl<K, F> FusedIterator for ExtractIf<'_, K, F> where F: FnMut(&K) -> bool {} -#[stable(feature = "hash_extract_if", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "hash_extract_if", since = "1.87.0")] impl<'a, K, F> fmt::Debug for ExtractIf<'a, K, F> where F: FnMut(&K) -> bool, diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs index 860ec3a6be1..d34e3ca00b9 100644 --- a/library/std/src/ffi/mod.rs +++ b/library/std/src/ffi/mod.rs @@ -201,5 +201,5 @@ pub use self::c_str::{CStr, CString}; #[doc(inline)] pub use self::os_str::{OsStr, OsString}; -#[stable(feature = "os_str_display", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "os_str_display", since = "1.87.0")] pub mod os_str; diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index aa25ff5293c..ce01175309a 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -1255,7 +1255,7 @@ impl OsStr { /// let s = OsStr::new("Hello, world!"); /// println!("{}", s.display()); /// ``` - #[stable(feature = "os_str_display", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "os_str_display", since = "1.87.0")] #[must_use = "this does not display the `OsStr`; \ it returns an object that can be displayed"] #[inline] @@ -1612,19 +1612,19 @@ impl fmt::Debug for OsStr { /// /// [`Display`]: fmt::Display /// [`format!`]: crate::format -#[stable(feature = "os_str_display", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "os_str_display", since = "1.87.0")] pub struct Display<'a> { os_str: &'a OsStr, } -#[stable(feature = "os_str_display", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "os_str_display", since = "1.87.0")] impl fmt::Debug for Display<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&self.os_str, f) } } -#[stable(feature = "os_str_display", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "os_str_display", since = "1.87.0")] impl fmt::Display for Display<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.os_str.inner, f) diff --git a/library/std/src/io/buffered/bufreader/buffer.rs b/library/std/src/io/buffered/bufreader/buffer.rs index 9fd2472ebdf..574288e579e 100644 --- a/library/std/src/io/buffered/bufreader/buffer.rs +++ b/library/std/src/io/buffered/bufreader/buffer.rs @@ -123,7 +123,6 @@ impl Buffer { /// Remove bytes that have already been read from the buffer. pub fn backshift(&mut self) { self.buf.copy_within(self.pos.., 0); - self.initialized -= self.pos; self.filled -= self.pos; self.pos = 0; } diff --git a/library/std/src/io/copy.rs b/library/std/src/io/copy.rs index 8d733325b3b..15e962924ac 100644 --- a/library/std/src/io/copy.rs +++ b/library/std/src/io/copy.rs @@ -248,8 +248,11 @@ impl<I: Write + ?Sized> BufferedWriterSpec for BufWriter<I> { Err(e) => return Err(e), } } else { + // All the bytes that were already in the buffer are initialized, + // treat them as such when the buffer is flushed. + init += buf.len(); + self.flush_buf()?; - init = 0; } } } diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 8472f903050..2498fb8d24f 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -374,7 +374,7 @@ pub enum ErrorKind { /// A filename was invalid. /// /// This error can also occur if a length limit for a name was exceeded. - #[stable(feature = "io_error_invalid_filename", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "io_error_invalid_filename", since = "1.87.0")] InvalidFilename, /// Program argument list too long. /// diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 314cbb45d49..b6545eada86 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -310,7 +310,7 @@ pub use self::error::RawOsError; pub use self::error::SimpleMessage; #[unstable(feature = "io_const_error", issue = "133448")] pub use self::error::const_error; -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] pub use self::pipe::{PipeReader, PipeWriter, pipe}; #[stable(feature = "is_terminal", since = "1.70.0")] pub use self::stdio::IsTerminal; diff --git a/library/std/src/io/pipe.rs b/library/std/src/io/pipe.rs index cfed9b05cc0..c6b7b49a351 100644 --- a/library/std/src/io/pipe.rs +++ b/library/std/src/io/pipe.rs @@ -67,19 +67,19 @@ use crate::sys_common::{FromInner, IntoInner}; /// ``` /// [changes]: io#platform-specific-behavior /// [man page]: https://man7.org/linux/man-pages/man7/pipe.7.html -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] #[inline] pub fn pipe() -> io::Result<(PipeReader, PipeWriter)> { pipe_inner().map(|(reader, writer)| (PipeReader(reader), PipeWriter(writer))) } /// Read end of an anonymous pipe. -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] #[derive(Debug)] pub struct PipeReader(pub(crate) AnonPipe); /// Write end of an anonymous pipe. -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] #[derive(Debug)] pub struct PipeWriter(pub(crate) AnonPipe); @@ -160,7 +160,7 @@ impl PipeReader { /// # Ok(()) /// # } /// ``` - #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "anonymous_pipe", since = "1.87.0")] pub fn try_clone(&self) -> io::Result<Self> { self.0.try_clone().map(Self) } @@ -199,13 +199,13 @@ impl PipeWriter { /// # Ok(()) /// # } /// ``` - #[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] + #[stable(feature = "anonymous_pipe", since = "1.87.0")] pub fn try_clone(&self) -> io::Result<Self> { self.0.try_clone().map(Self) } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl io::Read for &PipeReader { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) @@ -225,7 +225,7 @@ impl io::Read for &PipeReader { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl io::Read for PipeReader { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) @@ -245,7 +245,7 @@ impl io::Read for PipeReader { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl io::Write for &PipeWriter { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) @@ -263,7 +263,7 @@ impl io::Write for &PipeWriter { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl io::Write for PipeWriter { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 9dcedaa13f6..5c381181218 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -341,6 +341,7 @@ #![feature(exact_size_is_empty)] #![feature(exclusive_wrapper)] #![feature(extend_one)] +#![feature(float_algebraic)] #![feature(float_gamma)] #![feature(float_minimum_maximum)] #![feature(fmt_internals)] diff --git a/library/std/src/net/socket_addr.rs b/library/std/src/net/socket_addr.rs index 4c8905c0d46..41e623e79ce 100644 --- a/library/std/src/net/socket_addr.rs +++ b/library/std/src/net/socket_addr.rs @@ -101,7 +101,7 @@ use crate::{io, iter, option, slice, vec}; /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput); /// ``` /// -/// [`TcpStream::connect`] is an example of an function that utilizes +/// [`TcpStream::connect`] is an example of a function that utilizes /// `ToSocketAddrs` as a trait bound on its parameter in order to accept /// different types: /// diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index be73e7dee9c..10e1e73a115 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -505,7 +505,7 @@ impl<'a> AsFd for io::StderrLock<'a> { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] #[cfg(not(target_os = "trusty"))] impl AsFd for io::PipeReader { fn as_fd(&self) -> BorrowedFd<'_> { @@ -513,7 +513,7 @@ impl AsFd for io::PipeReader { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] #[cfg(not(target_os = "trusty"))] impl From<io::PipeReader> for OwnedFd { fn from(pipe: io::PipeReader) -> Self { @@ -521,7 +521,7 @@ impl From<io::PipeReader> for OwnedFd { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] #[cfg(not(target_os = "trusty"))] impl AsFd for io::PipeWriter { fn as_fd(&self) -> BorrowedFd<'_> { @@ -529,7 +529,7 @@ impl AsFd for io::PipeWriter { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] #[cfg(not(target_os = "trusty"))] impl From<io::PipeWriter> for OwnedFd { fn from(pipe: io::PipeWriter) -> Self { @@ -537,7 +537,7 @@ impl From<io::PipeWriter> for OwnedFd { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] #[cfg(not(target_os = "trusty"))] impl From<OwnedFd> for io::PipeReader { fn from(owned_fd: OwnedFd) -> Self { @@ -545,7 +545,7 @@ impl From<OwnedFd> for io::PipeReader { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] #[cfg(not(target_os = "trusty"))] impl From<OwnedFd> for io::PipeWriter { fn from(owned_fd: OwnedFd) -> Self { diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs index c800c1489ad..34a6cf1a8b8 100644 --- a/library/std/src/os/fd/raw.rs +++ b/library/std/src/os/fd/raw.rs @@ -285,7 +285,7 @@ impl<T: AsRawFd> AsRawFd for Box<T> { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] #[cfg(not(target_os = "trusty"))] impl AsRawFd for io::PipeReader { fn as_raw_fd(&self) -> RawFd { @@ -293,7 +293,7 @@ impl AsRawFd for io::PipeReader { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] #[cfg(not(target_os = "trusty"))] impl FromRawFd for io::PipeReader { unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { @@ -301,7 +301,7 @@ impl FromRawFd for io::PipeReader { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] #[cfg(not(target_os = "trusty"))] impl IntoRawFd for io::PipeReader { fn into_raw_fd(self) -> RawFd { @@ -309,7 +309,7 @@ impl IntoRawFd for io::PipeReader { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] #[cfg(not(target_os = "trusty"))] impl AsRawFd for io::PipeWriter { fn as_raw_fd(&self) -> RawFd { @@ -317,7 +317,7 @@ impl AsRawFd for io::PipeWriter { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] #[cfg(not(target_os = "trusty"))] impl FromRawFd for io::PipeWriter { unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { @@ -325,7 +325,7 @@ impl FromRawFd for io::PipeWriter { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] #[cfg(not(target_os = "trusty"))] impl IntoRawFd for io::PipeWriter { fn into_raw_fd(self) -> RawFd { diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs index 7f21929b85f..4fc04b79315 100644 --- a/library/std/src/os/windows/io/handle.rs +++ b/library/std/src/os/windows/io/handle.rs @@ -661,42 +661,42 @@ impl<T> From<crate::thread::JoinHandle<T>> for OwnedHandle { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl AsHandle for io::PipeReader { fn as_handle(&self) -> BorrowedHandle<'_> { self.0.as_handle() } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl From<io::PipeReader> for OwnedHandle { fn from(pipe: io::PipeReader) -> Self { pipe.into_inner().into_inner() } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl AsHandle for io::PipeWriter { fn as_handle(&self) -> BorrowedHandle<'_> { self.0.as_handle() } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl From<io::PipeWriter> for OwnedHandle { fn from(pipe: io::PipeWriter) -> Self { pipe.into_inner().into_inner() } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl From<OwnedHandle> for io::PipeReader { fn from(owned_handle: OwnedHandle) -> Self { Self::from_inner(FromInner::from_inner(owned_handle)) } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl From<OwnedHandle> for io::PipeWriter { fn from(owned_handle: OwnedHandle) -> Self { Self::from_inner(FromInner::from_inner(owned_handle)) diff --git a/library/std/src/os/windows/io/raw.rs b/library/std/src/os/windows/io/raw.rs index bc3e55c8629..a3ec7440338 100644 --- a/library/std/src/os/windows/io/raw.rs +++ b/library/std/src/os/windows/io/raw.rs @@ -311,42 +311,42 @@ impl IntoRawSocket for net::UdpSocket { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl AsRawHandle for io::PipeReader { fn as_raw_handle(&self) -> RawHandle { self.0.as_raw_handle() } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl FromRawHandle for io::PipeReader { unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self { unsafe { Self::from_inner(FromRawHandle::from_raw_handle(raw_handle)) } } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl IntoRawHandle for io::PipeReader { fn into_raw_handle(self) -> RawHandle { self.0.into_raw_handle() } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl AsRawHandle for io::PipeWriter { fn as_raw_handle(&self) -> RawHandle { self.0.as_raw_handle() } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl FromRawHandle for io::PipeWriter { unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self { unsafe { Self::from_inner(FromRawHandle::from_raw_handle(raw_handle)) } } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl IntoRawHandle for io::PipeWriter { fn into_raw_handle(self) -> RawHandle { self.0.into_raw_handle() diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index b35549c92ad..a3950980b5e 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -55,14 +55,14 @@ pub static EMPTY_PANIC: fn(&'static str) -> ! = // hook up these functions, but it is not this day! #[allow(improper_ctypes)] unsafe extern "C" { - #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)] + #[rustc_std_internal_symbol] fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static); } unsafe extern "Rust" { /// `PanicPayload` lazily performs allocation only when needed (this avoids /// allocations when using the "abort" panic runtime). - #[cfg_attr(not(bootstrap), rustc_std_internal_symbol)] + #[rustc_std_internal_symbol] fn __rust_start_panic(payload: &mut dyn PanicPayload) -> u32; } diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index 4217f658640..c15d8c40085 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -109,7 +109,6 @@ pub use core::prelude::v1::deref; issue = "63063", reason = "`type_alias_impl_trait` has open design concerns" )] -#[cfg(not(bootstrap))] pub use core::prelude::v1::define_opaque; // The file so far is equivalent to core/src/prelude/v1.rs. It is duplicated diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 3b765a9537b..da518011a0e 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -1659,14 +1659,14 @@ impl From<io::Stderr> for Stdio { } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl From<io::PipeWriter> for Stdio { fn from(pipe: io::PipeWriter) -> Self { Stdio::from_inner(pipe.into_inner().into()) } } -#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")] +#[stable(feature = "anonymous_pipe", since = "1.87.0")] impl From<io::PipeReader> for Stdio { fn from(pipe: io::PipeReader) -> Self { Stdio::from_inner(pipe.into_inner().into()) diff --git a/library/std/src/sync/poison/mutex.rs b/library/std/src/sync/poison/mutex.rs index 9362c764173..adb74bb6f3d 100644 --- a/library/std/src/sync/poison/mutex.rs +++ b/library/std/src/sync/poison/mutex.rs @@ -582,7 +582,9 @@ impl<T: ?Sized> Mutex<T> { /// Returns a mutable reference to the underlying data. /// /// Since this call borrows the `Mutex` mutably, no actual locking needs to - /// take place -- the mutable borrow statically guarantees no locks exist. + /// take place -- the mutable borrow statically guarantees no new locks can be acquired + /// while this reference exists. Note that this method does not clear any previous abandoned locks + /// (e.g., via [`forget()`] on a [`MutexGuard`]). /// /// # Errors /// @@ -599,6 +601,8 @@ impl<T: ?Sized> Mutex<T> { /// *mutex.get_mut().unwrap() = 10; /// assert_eq!(*mutex.lock().unwrap(), 10); /// ``` + /// + /// [`forget()`]: mem::forget #[stable(feature = "mutex_get_mut", since = "1.6.0")] pub fn get_mut(&mut self) -> LockResult<&mut T> { let data = self.data.get_mut(); diff --git a/library/std/src/sync/poison/rwlock.rs b/library/std/src/sync/poison/rwlock.rs index f9d9321f5f2..a2abd4f692e 100644 --- a/library/std/src/sync/poison/rwlock.rs +++ b/library/std/src/sync/poison/rwlock.rs @@ -608,7 +608,9 @@ impl<T: ?Sized> RwLock<T> { /// Returns a mutable reference to the underlying data. /// /// Since this call borrows the `RwLock` mutably, no actual locking needs to - /// take place -- the mutable borrow statically guarantees no locks exist. + /// take place -- the mutable borrow statically guarantees no new locks can be acquired + /// while this reference exists. Note that this method does not clear any previously abandoned locks + /// (e.g., via [`forget()`] on a [`RwLockReadGuard`] or [`RwLockWriteGuard`]). /// /// # Errors /// diff --git a/library/std/src/sys/pal/hermit/fd.rs b/library/std/src/sys/fd/hermit.rs index edd984d920a..7e8ba065f1b 100644 --- a/library/std/src/sys/pal/hermit/fd.rs +++ b/library/std/src/sys/fd/hermit.rs @@ -1,8 +1,8 @@ #![unstable(reason = "not public", issue = "none", feature = "fd")] -use super::hermit_abi; use crate::cmp; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read, SeekFrom}; +use crate::os::hermit::hermit_abi; use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use crate::sys::{cvt, unsupported}; use crate::sys_common::{AsInner, FromInner, IntoInner}; diff --git a/library/std/src/sys/fd/mod.rs b/library/std/src/sys/fd/mod.rs new file mode 100644 index 00000000000..e0f5eab6951 --- /dev/null +++ b/library/std/src/sys/fd/mod.rs @@ -0,0 +1,19 @@ +//! Platform-dependent file descriptor abstraction. + +#![forbid(unsafe_op_in_unsafe_fn)] + +cfg_if::cfg_if! { + if #[cfg(target_family = "unix")] { + mod unix; + pub use unix::*; + } else if #[cfg(target_os = "hermit")] { + mod hermit; + pub use hermit::*; + } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { + mod sgx; + pub use sgx::*; + } else if #[cfg(target_os = "wasi")] { + mod wasi; + pub use wasi::*; + } +} diff --git a/library/std/src/sys/pal/sgx/fd.rs b/library/std/src/sys/fd/sgx.rs index 399f6a16489..1ef768db64c 100644 --- a/library/std/src/sys/pal/sgx/fd.rs +++ b/library/std/src/sys/fd/sgx.rs @@ -1,8 +1,8 @@ use fortanix_sgx_abi::Fd; -use super::abi::usercalls; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::mem::ManuallyDrop; +use crate::sys::pal::abi::usercalls; use crate::sys::{AsInner, FromInner, IntoInner}; #[derive(Debug)] diff --git a/library/std/src/sys/pal/unix/fd.rs b/library/std/src/sys/fd/unix.rs index 2ec8d01c13f..2042ea2c73d 100644 --- a/library/std/src/sys/pal/unix/fd.rs +++ b/library/std/src/sys/fd/unix.rs @@ -22,6 +22,10 @@ use crate::cmp; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read}; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use crate::sys::cvt; +#[cfg(all(target_os = "android", target_pointer_width = "64"))] +use crate::sys::pal::weak::syscall; +#[cfg(any(all(target_os = "android", target_pointer_width = "32"), target_vendor = "apple"))] +use crate::sys::pal::weak::weak; use crate::sys_common::{AsInner, FromInner, IntoInner}; #[derive(Debug)] @@ -232,7 +236,7 @@ impl FileDesc { // implementation if `preadv` is not available. #[cfg(all(target_os = "android", target_pointer_width = "64"))] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> { - super::weak::syscall!( + syscall!( fn preadv( fd: libc::c_int, iovec: *const libc::iovec, @@ -257,7 +261,7 @@ impl FileDesc { // and its metadata from LLVM IR. #[no_sanitize(cfi)] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> { - super::weak::weak!( + weak!( fn preadv64( fd: libc::c_int, iovec: *const libc::iovec, @@ -293,7 +297,7 @@ impl FileDesc { // use "weak" linking. #[cfg(target_vendor = "apple")] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> { - super::weak::weak!( + weak!( fn preadv( fd: libc::c_int, iovec: *const libc::iovec, @@ -442,7 +446,7 @@ impl FileDesc { // implementation if `pwritev` is not available. #[cfg(all(target_os = "android", target_pointer_width = "64"))] pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> { - super::weak::syscall!( + syscall!( fn pwritev( fd: libc::c_int, iovec: *const libc::iovec, @@ -464,7 +468,7 @@ impl FileDesc { #[cfg(all(target_os = "android", target_pointer_width = "32"))] pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> { - super::weak::weak!( + weak!( fn pwritev64( fd: libc::c_int, iovec: *const libc::iovec, @@ -500,7 +504,7 @@ impl FileDesc { // use "weak" linking. #[cfg(target_vendor = "apple")] pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> { - super::weak::weak!( + weak!( fn pwritev( fd: libc::c_int, iovec: *const libc::iovec, @@ -669,6 +673,6 @@ impl IntoRawFd for FileDesc { impl FromRawFd for FileDesc { unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { - Self(FromRawFd::from_raw_fd(raw_fd)) + Self(unsafe { FromRawFd::from_raw_fd(raw_fd) }) } } diff --git a/library/std/src/sys/pal/unix/fd/tests.rs b/library/std/src/sys/fd/unix/tests.rs index c5301ce6557..fcd66c71707 100644 --- a/library/std/src/sys/pal/unix/fd/tests.rs +++ b/library/std/src/sys/fd/unix/tests.rs @@ -1,6 +1,7 @@ use core::mem::ManuallyDrop; -use super::{FileDesc, IoSlice}; +use super::FileDesc; +use crate::io::IoSlice; use crate::os::unix::io::FromRawFd; #[test] diff --git a/library/std/src/sys/pal/wasi/fd.rs b/library/std/src/sys/fd/wasi.rs index 4b3dd1ce49e..80a5143ff0b 100644 --- a/library/std/src/sys/pal/wasi/fd.rs +++ b/library/std/src/sys/fd/wasi.rs @@ -1,11 +1,10 @@ -#![forbid(unsafe_op_in_unsafe_fn)] -#![allow(dead_code)] +#![expect(dead_code)] -use super::err2io; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; use crate::mem; use crate::net::Shutdown; use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; +use crate::sys::pal::err2io; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; #[derive(Debug)] diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs index f83a2f90ed2..99690abe8ed 100644 --- a/library/std/src/sys/fs/hermit.rs +++ b/library/std/src/sys/fs/hermit.rs @@ -9,8 +9,8 @@ use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, Raw use crate::path::{Path, PathBuf}; use crate::sync::Arc; use crate::sys::common::small_c_string::run_path_with_cstr; +use crate::sys::fd::FileDesc; pub use crate::sys::fs::common::{copy, exists}; -use crate::sys::pal::fd::FileDesc; use crate::sys::time::SystemTime; use crate::sys::{cvt, unsupported}; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs index 06bba019393..15727c99683 100644 --- a/library/std/src/sys/fs/windows.rs +++ b/library/std/src/sys/fs/windows.rs @@ -547,7 +547,7 @@ impl File { ))?; attr.file_size = info.AllocationSize as u64; attr.number_of_links = Some(info.NumberOfLinks); - if attr.file_type().is_reparse_point() { + if attr.attributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 { let mut attr_tag: c::FILE_ATTRIBUTE_TAG_INFO = mem::zeroed(); cvt(c::GetFileInformationByHandleEx( self.handle.as_raw_handle(), diff --git a/library/std/src/sys/io/io_slice/iovec.rs b/library/std/src/sys/io/io_slice/iovec.rs index 072191315f7..df56358969a 100644 --- a/library/std/src/sys/io/io_slice/iovec.rs +++ b/library/std/src/sys/io/io_slice/iovec.rs @@ -1,6 +1,6 @@ #[cfg(target_os = "hermit")] use hermit_abi::iovec; -#[cfg(target_family = "unix")] +#[cfg(any(target_family = "unix", target_os = "trusty"))] use libc::iovec; use crate::ffi::c_void; diff --git a/library/std/src/sys/io/mod.rs b/library/std/src/sys/io/mod.rs index e00b479109f..4d0365d42fd 100644 --- a/library/std/src/sys/io/mod.rs +++ b/library/std/src/sys/io/mod.rs @@ -2,7 +2,7 @@ mod io_slice { cfg_if::cfg_if! { - if #[cfg(any(target_family = "unix", target_os = "hermit", target_os = "solid_asp3"))] { + if #[cfg(any(target_family = "unix", target_os = "hermit", target_os = "solid_asp3", target_os = "trusty"))] { mod iovec; pub use iovec::*; } else if #[cfg(target_os = "windows")] { diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index f0cfb9b2773..f8f220fafd1 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -12,6 +12,7 @@ pub mod anonymous_pipe; pub mod backtrace; pub mod cmath; pub mod exit_guard; +pub mod fd; pub mod fs; pub mod io; pub mod net; diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs index 67eab96fa40..26211bcb152 100644 --- a/library/std/src/sys/pal/hermit/mod.rs +++ b/library/std/src/sys/pal/hermit/mod.rs @@ -20,7 +20,6 @@ use crate::os::raw::c_char; pub mod args; pub mod env; -pub mod fd; pub mod futex; pub mod os; #[path = "../unsupported/pipe.rs"] diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index fe43cfd2caf..52684e18ac2 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs @@ -11,7 +11,6 @@ use crate::sync::atomic::{AtomicBool, Ordering}; pub mod abi; pub mod args; pub mod env; -pub mod fd; mod libunwind_integration; pub mod os; #[path = "../unsupported/pipe.rs"] diff --git a/library/std/src/sys/pal/unix/linux/pidfd.rs b/library/std/src/sys/pal/unix/linux/pidfd.rs index 78744430f3b..2d949ec9e91 100644 --- a/library/std/src/sys/pal/unix/linux/pidfd.rs +++ b/library/std/src/sys/pal/unix/linux/pidfd.rs @@ -1,7 +1,7 @@ use crate::io; use crate::os::fd::{AsRawFd, FromRawFd, RawFd}; use crate::sys::cvt; -use crate::sys::pal::unix::fd::FileDesc; +use crate::sys::fd::FileDesc; use crate::sys::process::ExitStatus; use crate::sys_common::{AsInner, FromInner, IntoInner}; diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 413fda1d8d8..d7106c33974 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -8,7 +8,6 @@ pub mod weak; pub mod args; pub mod env; -pub mod fd; #[cfg(target_os = "fuchsia")] pub mod fuchsia; pub mod futex; diff --git a/library/std/src/sys/pal/unix/weak.rs b/library/std/src/sys/pal/unix/weak.rs index e7f4e005cc4..e4c814fba8c 100644 --- a/library/std/src/sys/pal/unix/weak.rs +++ b/library/std/src/sys/pal/unix/weak.rs @@ -20,6 +20,7 @@ // each instance of `weak!` and `syscall!`. Rather than trying to unify all of // that, we'll just allow that some unix targets don't use this module at all. #![allow(dead_code, unused_macros)] +#![forbid(unsafe_op_in_unsafe_fn)] use crate::ffi::CStr; use crate::marker::PhantomData; @@ -131,11 +132,15 @@ impl<F> DlsymWeak<F> { unsafe fn initialize(&self) -> Option<F> { assert_eq!(size_of::<F>(), size_of::<*mut libc::c_void>()); - let val = fetch(self.name); + let val = unsafe { fetch(self.name) }; // This synchronizes with the acquire fence in `get`. self.func.store(val, Ordering::Release); - if val.is_null() { None } else { Some(mem::transmute_copy::<*mut libc::c_void, F>(&val)) } + if val.is_null() { + None + } else { + Some(unsafe { mem::transmute_copy::<*mut libc::c_void, F>(&val) }) + } } } @@ -144,7 +149,7 @@ unsafe fn fetch(name: &str) -> *mut libc::c_void { Ok(cstr) => cstr, Err(..) => return ptr::null_mut(), }; - libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr()) + unsafe { libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr()) } } #[cfg(not(any(target_os = "linux", target_os = "android")))] @@ -157,7 +162,7 @@ pub(crate) macro syscall { weak!(fn $name($($param: $t),*) -> $ret;); if let Some(fun) = $name.get() { - fun($($param),*) + unsafe { fun($($param),*) } } else { super::os::set_errno(libc::ENOSYS); -1 @@ -177,9 +182,9 @@ pub(crate) macro syscall { // Use a weak symbol from libc when possible, allowing `LD_PRELOAD` // interposition, but if it's not found just use a raw syscall. if let Some(fun) = $name.get() { - fun($($param),*) + unsafe { fun($($param),*) } } else { - libc::syscall(libc::${concat(SYS_, $name)}, $($param),*) as $ret + unsafe { libc::syscall(libc::${concat(SYS_, $name)}, $($param),*) as $ret } } } ) @@ -189,7 +194,7 @@ pub(crate) macro syscall { pub(crate) macro raw_syscall { (fn $name:ident($($param:ident : $t:ty),* $(,)?) -> $ret:ty;) => ( unsafe fn $name($($param: $t),*) -> $ret { - libc::syscall(libc::${concat(SYS_, $name)}, $($param),*) as $ret + unsafe { libc::syscall(libc::${concat(SYS_, $name)}, $($param),*) as $ret } } ) } diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs index cdd613f76b6..80853e7b5a2 100644 --- a/library/std/src/sys/pal/wasi/mod.rs +++ b/library/std/src/sys/pal/wasi/mod.rs @@ -15,7 +15,6 @@ pub mod args; pub mod env; -pub mod fd; #[allow(unused)] #[path = "../wasm/atomics/futex.rs"] pub mod futex; diff --git a/library/std/src/sys/pal/wasip2/mod.rs b/library/std/src/sys/pal/wasip2/mod.rs index 6ac28f1bf4f..504b947d09e 100644 --- a/library/std/src/sys/pal/wasip2/mod.rs +++ b/library/std/src/sys/pal/wasip2/mod.rs @@ -10,8 +10,6 @@ pub mod args; #[path = "../wasi/env.rs"] pub mod env; -#[path = "../wasi/fd.rs"] -pub mod fd; #[allow(unused)] #[path = "../wasm/atomics/futex.rs"] pub mod futex; @@ -39,7 +37,6 @@ mod helpers; // import conflict rules. If we glob export `helpers` and `common` together, // then the compiler complains about conflicts. -use helpers::err2io; -pub use helpers::{abort_internal, decode_error_kind, is_interrupted}; +pub(crate) use helpers::{abort_internal, decode_error_kind, err2io, is_interrupted}; mod cabi_realloc; diff --git a/library/std/src/sys/pal/windows/pipe.rs b/library/std/src/sys/pal/windows/pipe.rs index c7852464922..7fd62339619 100644 --- a/library/std/src/sys/pal/windows/pipe.rs +++ b/library/std/src/sys/pal/windows/pipe.rs @@ -143,7 +143,6 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res }; opts.security_attributes(&mut sa); let theirs = File::open(Path::new(&name), &opts)?; - let theirs = AnonPipe { inner: theirs.into_inner() }; Ok(Pipes { ours: AnonPipe { inner: ours }, diff --git a/library/std/src/sys/path/windows.rs b/library/std/src/sys/path/windows.rs index 1c534721916..6547ed9aa5f 100644 --- a/library/std/src/sys/path/windows.rs +++ b/library/std/src/sys/path/windows.rs @@ -350,3 +350,46 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> { pub(crate) fn is_absolute(path: &Path) -> bool { path.has_root() && path.prefix().is_some() } + +/// Test that the path is absolute, fully qualified and unchanged when processed by the Windows API. +/// +/// For example: +/// +/// - `C:\path\to\file` will return true. +/// - `C:\path\to\nul` returns false because the Windows API will convert it to \\.\NUL +/// - `C:\path\to\..\file` returns false because it will be resolved to `C:\path\file`. +/// +/// This is a useful property because it means the path can be converted from and to and verbatim +/// path just by changing the prefix. +pub(crate) fn is_absolute_exact(path: &[u16]) -> bool { + // This is implemented by checking that passing the path through + // GetFullPathNameW does not change the path in any way. + + // Windows paths are limited to i16::MAX length + // though the API here accepts a u32 for the length. + if path.is_empty() || path.len() > u32::MAX as usize || path.last() != Some(&0) { + return false; + } + // The path returned by `GetFullPathNameW` must be the same length as the + // given path, otherwise they're not equal. + let buffer_len = path.len(); + let mut new_path = Vec::with_capacity(buffer_len); + let result = unsafe { + c::GetFullPathNameW( + path.as_ptr(), + new_path.capacity() as u32, + new_path.as_mut_ptr(), + crate::ptr::null_mut(), + ) + }; + // Note: if non-zero, the returned result is the length of the buffer without the null termination + if result == 0 || result as usize != buffer_len - 1 { + false + } else { + // SAFETY: `GetFullPathNameW` initialized `result` bytes and does not exceed `nBufferLength - 1` (capacity). + unsafe { + new_path.set_len((result as usize) + 1); + } + path == &new_path + } +} diff --git a/library/std/src/sys/path/windows/tests.rs b/library/std/src/sys/path/windows/tests.rs index f2a60e30bc6..9eb79203dca 100644 --- a/library/std/src/sys/path/windows/tests.rs +++ b/library/std/src/sys/path/windows/tests.rs @@ -135,3 +135,15 @@ fn broken_unc_path() { assert_eq!(components.next(), Some(Component::Normal("foo".as_ref()))); assert_eq!(components.next(), Some(Component::Normal("bar".as_ref()))); } + +#[test] +fn test_is_absolute_exact() { + use crate::sys::pal::api::wide_str; + // These paths can be made verbatim by only changing their prefix. + assert!(is_absolute_exact(wide_str!(r"C:\path\to\file"))); + assert!(is_absolute_exact(wide_str!(r"\\server\share\path\to\file"))); + // These paths change more substantially + assert!(!is_absolute_exact(wide_str!(r"C:\path\to\..\file"))); + assert!(!is_absolute_exact(wide_str!(r"\\server\share\path\to\..\file"))); + assert!(!is_absolute_exact(wide_str!(r"C:\path\to\NUL"))); // Converts to \\.\NUL +} diff --git a/library/std/src/sys/process/windows.rs b/library/std/src/sys/process/windows.rs index 06c15e08f3f..4cfdf908c58 100644 --- a/library/std/src/sys/process/windows.rs +++ b/library/std/src/sys/process/windows.rs @@ -19,7 +19,7 @@ use crate::sys::args::{self, Arg}; use crate::sys::c::{self, EXIT_FAILURE, EXIT_SUCCESS}; use crate::sys::fs::{File, OpenOptions}; use crate::sys::handle::Handle; -use crate::sys::pal::api::{self, WinError}; +use crate::sys::pal::api::{self, WinError, utf16}; use crate::sys::pal::{ensure_no_nuls, fill_utf16_buf}; use crate::sys::pipe::{self, AnonPipe}; use crate::sys::{cvt, path, stdio}; @@ -880,9 +880,33 @@ fn make_envp(maybe_env: Option<BTreeMap<EnvKey, OsString>>) -> io::Result<(*mut fn make_dirp(d: Option<&OsString>) -> io::Result<(*const u16, Vec<u16>)> { match d { Some(dir) => { - let mut dir_str: Vec<u16> = ensure_no_nuls(dir)?.encode_wide().collect(); - dir_str.push(0); - Ok((dir_str.as_ptr(), dir_str)) + let mut dir_str: Vec<u16> = ensure_no_nuls(dir)?.encode_wide().chain([0]).collect(); + // Try to remove the `\\?\` prefix, if any. + // This is necessary because the current directory does not support verbatim paths. + // However. this can only be done if it doesn't change how the path will be resolved. + let ptr = if dir_str.starts_with(utf16!(r"\\?\UNC")) { + // Turn the `C` in `UNC` into a `\` so we can then use `\\rest\of\path`. + let start = r"\\?\UN".len(); + dir_str[start] = b'\\' as u16; + if path::is_absolute_exact(&dir_str[start..]) { + dir_str[start..].as_ptr() + } else { + // Revert the above change. + dir_str[start] = b'C' as u16; + dir_str.as_ptr() + } + } else if dir_str.starts_with(utf16!(r"\\?\")) { + // Strip the leading `\\?\` + let start = r"\\?\".len(); + if path::is_absolute_exact(&dir_str[start..]) { + dir_str[start..].as_ptr() + } else { + dir_str.as_ptr() + } + } else { + dir_str.as_ptr() + }; + Ok((ptr, dir_str)) } None => Ok((ptr::null(), Vec::new())), } diff --git a/library/std/src/sys/stdio/trusty.rs b/library/std/src/sys/stdio/trusty.rs index d393e95394d..e05461aa44a 100644 --- a/library/std/src/sys/stdio/trusty.rs +++ b/library/std/src/sys/stdio/trusty.rs @@ -1,21 +1,14 @@ -use crate::io; +#[expect(dead_code)] +#[path = "unsupported.rs"] +mod unsupported_stdio; -pub struct Stdin; +use crate::cmp; +use crate::io::{self, IoSlice}; + +pub type Stdin = unsupported_stdio::Stdin; pub struct Stdout; pub struct Stderr; -impl Stdin { - pub const fn new() -> Stdin { - Stdin - } -} - -impl io::Read for Stdin { - fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { - Ok(0) - } -} - impl Stdout { pub const fn new() -> Stdout { Stdout @@ -24,7 +17,16 @@ impl Stdout { impl io::Write for Stdout { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - _write(libc::STDOUT_FILENO, buf) + write(libc::STDOUT_FILENO, buf) + } + + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { + write_vectored(libc::STDOUT_FILENO, bufs) + } + + #[inline] + fn is_write_vectored(&self) -> bool { + true } fn flush(&mut self) -> io::Result<()> { @@ -40,7 +42,16 @@ impl Stderr { impl io::Write for Stderr { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - _write(libc::STDERR_FILENO, buf) + write(libc::STDERR_FILENO, buf) + } + + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { + write_vectored(libc::STDERR_FILENO, bufs) + } + + #[inline] + fn is_write_vectored(&self) -> bool { + true } fn flush(&mut self) -> io::Result<()> { @@ -48,7 +59,7 @@ impl io::Write for Stderr { } } -pub const STDIN_BUF_SIZE: usize = 0; +pub const STDIN_BUF_SIZE: usize = unsupported_stdio::STDIN_BUF_SIZE; pub fn is_ebadf(_err: &io::Error) -> bool { true @@ -58,24 +69,24 @@ pub fn panic_output() -> Option<impl io::Write> { Some(Stderr) } -fn _write(fd: i32, message: &[u8]) -> io::Result<usize> { - let mut iov = libc::iovec { iov_base: message.as_ptr() as *mut _, iov_len: message.len() }; - loop { - // SAFETY: syscall, safe arguments. - let ret = unsafe { libc::writev(fd, &iov, 1) }; - if ret < 0 { - return Err(io::Error::last_os_error()); - } - let ret = ret as usize; - if ret > iov.iov_len { - return Err(io::Error::last_os_error()); - } - if ret == iov.iov_len { - return Ok(message.len()); - } - // SAFETY: ret has been checked to be less than the length of - // the buffer - iov.iov_base = unsafe { iov.iov_base.add(ret) }; - iov.iov_len -= ret; +fn write(fd: i32, buf: &[u8]) -> io::Result<usize> { + let iov = libc::iovec { iov_base: buf.as_ptr() as *mut _, iov_len: buf.len() }; + // SAFETY: syscall, safe arguments. + let ret = unsafe { libc::writev(fd, &iov, 1) }; + // This check includes ret < 0, since the length is at most isize::MAX. + if ret as usize > iov.iov_len { + return Err(io::Error::last_os_error()); + } + Ok(ret as usize) +} + +fn write_vectored(fd: i32, bufs: &[IoSlice<'_>]) -> io::Result<usize> { + let iov = bufs.as_ptr() as *const libc::iovec; + let len = cmp::min(bufs.len(), libc::c_int::MAX as usize) as libc::c_int; + // SAFETY: syscall, safe arguments. + let ret = unsafe { libc::writev(fd, iov, len) }; + if ret < 0 { + return Err(io::Error::last_os_error()); } + Ok(ret as usize) } diff --git a/library/std/src/sys/stdio/wasi.rs b/library/std/src/sys/stdio/wasi.rs index 8105b0cfa2f..b70efd026f9 100644 --- a/library/std/src/sys/stdio/wasi.rs +++ b/library/std/src/sys/stdio/wasi.rs @@ -4,7 +4,7 @@ use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::mem::ManuallyDrop; use crate::os::raw; use crate::os::wasi::io::{AsRawFd, FromRawFd}; -use crate::sys::pal::fd::WasiFd; +use crate::sys::fd::WasiFd; pub struct Stdin; pub struct Stdout; diff --git a/library/std/src/sys/thread_local/mod.rs b/library/std/src/sys/thread_local/mod.rs index 1ff13154b7b..9fafac3aa5b 100644 --- a/library/std/src/sys/thread_local/mod.rs +++ b/library/std/src/sys/thread_local/mod.rs @@ -30,9 +30,9 @@ cfg_if::cfg_if! { target_os = "zkvm", target_os = "trusty", ))] { - mod statik; - pub use statik::{EagerStorage, LazyStorage, thread_local_inner}; - pub(crate) use statik::{LocalPointer, local_pointer}; + mod no_threads; + pub use no_threads::{EagerStorage, LazyStorage, thread_local_inner}; + pub(crate) use no_threads::{LocalPointer, local_pointer}; } else if #[cfg(target_thread_local)] { mod native; pub use native::{EagerStorage, LazyStorage, thread_local_inner}; @@ -138,6 +138,7 @@ pub(crate) mod key { not(target_family = "wasm"), target_family = "unix", ), + all(not(target_thread_local), target_vendor = "apple"), target_os = "teeos", all(target_os = "wasi", target_env = "p1", target_feature = "atomics"), ))] { diff --git a/library/std/src/sys/thread_local/statik.rs b/library/std/src/sys/thread_local/no_threads.rs index 4da01a84acf..4da01a84acf 100644 --- a/library/std/src/sys/thread_local/statik.rs +++ b/library/std/src/sys/thread_local/no_threads.rs |
