From 4bb0a5ed7ff9f959c1a61f43dd796c3f18e8b260 Mon Sep 17 00:00:00 2001 From: EFanZh <efanzh@gmail.com> Date: Tue, 7 Feb 2023 00:57:43 +0800 Subject: [PATCH 1/7] Inline `Poll` methods --- library/core/src/task/poll.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs index 25b61c0e66641..af5bf441bb25f 100644 --- a/library/core/src/task/poll.rs +++ b/library/core/src/task/poll.rs @@ -45,6 +45,7 @@ impl<T> Poll<T> { /// assert_eq!(poll_some_len, Poll::Ready(13)); /// ``` #[stable(feature = "futures_api", since = "1.36.0")] + #[inline] pub fn map<U, F>(self, f: F) -> Poll<U> where F: FnOnce(T) -> U, @@ -144,6 +145,7 @@ impl<T, E> Poll<Result<T, E>> { /// assert_eq!(squared, Poll::Ready(Ok(144))); /// ``` #[stable(feature = "futures_api", since = "1.36.0")] + #[inline] pub fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>> where F: FnOnce(T) -> U, @@ -171,6 +173,7 @@ impl<T, E> Poll<Result<T, E>> { /// assert_eq!(res, Poll::Ready(Err(0))); /// ``` #[stable(feature = "futures_api", since = "1.36.0")] + #[inline] pub fn map_err<U, F>(self, f: F) -> Poll<Result<T, U>> where F: FnOnce(E) -> U, @@ -199,6 +202,7 @@ impl<T, E> Poll<Option<Result<T, E>>> { /// assert_eq!(squared, Poll::Ready(Some(Ok(144)))); /// ``` #[stable(feature = "poll_map", since = "1.51.0")] + #[inline] pub fn map_ok<U, F>(self, f: F) -> Poll<Option<Result<U, E>>> where F: FnOnce(T) -> U, @@ -228,6 +232,7 @@ impl<T, E> Poll<Option<Result<T, E>>> { /// assert_eq!(res, Poll::Ready(Some(Err(0)))); /// ``` #[stable(feature = "poll_map", since = "1.51.0")] + #[inline] pub fn map_err<U, F>(self, f: F) -> Poll<Option<Result<T, U>>> where F: FnOnce(E) -> U, From 8ffb6af439fe6662cc90794fb75934a0f525be40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= <tomasz.miasko@gmail.com> Date: Tue, 21 Feb 2023 00:00:00 +0000 Subject: [PATCH 2/7] Implement read_buf for a few more types Implement read_buf for TcpStream, Stdin, StdinLock, ChildStdout, ChildStderr (and internally for AnonPipe, Handle, Socket), so that it skips buffer initialization. The other provided methods like read_to_string and read_to_end are implemented in terms of read_buf and so benefit from the optimization as well. This commit also implements read_vectored and is_read_vectored where applicable. --- library/std/src/fs/tests.rs | 20 +++++++++++++++- library/std/src/io/stdio.rs | 13 ++++++++++- library/std/src/net/tcp.rs | 10 +++++++- library/std/src/net/tcp/tests.rs | 24 ++++++++++++++++++- library/std/src/process.rs | 10 +++++++- library/std/src/process/tests.rs | 31 ++++++++++++++++++++++++- library/std/src/sys/unix/fd.rs | 9 +++++++ library/std/src/sys/unix/net.rs | 28 +++++++++++++++++----- library/std/src/sys/unix/pipe.rs | 6 ++++- library/std/src/sys/unix/stdio.rs | 6 ++++- library/std/src/sys/unsupported/pipe.rs | 6 ++++- library/std/src/sys/windows/handle.rs | 9 +++++++ library/std/src/sys/windows/net.rs | 28 +++++++++++++++------- library/std/src/sys/windows/pipe.rs | 24 ++++++++++++++++++- library/std/src/sys_common/net.rs | 6 ++++- 15 files changed, 205 insertions(+), 25 deletions(-) diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 839fdc96632d1..960cbc99c9767 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -2,7 +2,8 @@ use crate::io::prelude::*; use crate::env; use crate::fs::{self, File, OpenOptions}; -use crate::io::{ErrorKind, SeekFrom}; +use crate::io::{BorrowedBuf, ErrorKind, SeekFrom}; +use crate::mem::MaybeUninit; use crate::path::Path; use crate::str; use crate::sync::Arc; @@ -401,6 +402,23 @@ fn file_test_io_seek_read_write() { check!(fs::remove_file(&filename)); } +#[test] +fn file_test_read_buf() { + let tmpdir = tmpdir(); + let filename = &tmpdir.join("test"); + check!(fs::write(filename, &[1, 2, 3, 4])); + + let mut buf: [MaybeUninit<u8>; 128] = MaybeUninit::uninit_array(); + let mut buf = BorrowedBuf::from(buf.as_mut_slice()); + let mut file = check!(File::open(filename)); + check!(file.read_buf(buf.unfilled())); + assert_eq!(buf.filled(), &[1, 2, 3, 4]); + // File::read_buf should omit buffer initialization. + assert_eq!(buf.init_len(), 4); + + check!(fs::remove_file(filename)); +} + #[test] fn file_test_stat_is_correct_on_is_file() { let tmpdir = tmpdir(); diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index 14bfef4c7aad9..0455a00956e6f 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -8,7 +8,7 @@ use crate::io::prelude::*; use crate::cell::{Cell, RefCell}; use crate::fmt; use crate::fs::File; -use crate::io::{self, BufReader, IoSlice, IoSliceMut, LineWriter, Lines}; +use crate::io::{self, BorrowedCursor, BufReader, IoSlice, IoSliceMut, LineWriter, Lines}; use crate::sync::atomic::{AtomicBool, Ordering}; use crate::sync::{Arc, Mutex, MutexGuard, OnceLock, ReentrantMutex, ReentrantMutexGuard}; use crate::sys::stdio; @@ -97,6 +97,10 @@ impl Read for StdinRaw { handle_ebadf(self.0.read(buf), 0) } + fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { + handle_ebadf(self.0.read_buf(buf), ()) + } + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { handle_ebadf(self.0.read_vectored(bufs), 0) } @@ -418,6 +422,9 @@ impl Read for Stdin { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.lock().read(buf) } + fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { + self.lock().read_buf(buf) + } fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { self.lock().read_vectored(bufs) } @@ -450,6 +457,10 @@ impl Read for StdinLock<'_> { self.inner.read(buf) } + fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { + self.inner.read_buf(buf) + } + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { self.inner.read_vectored(bufs) } diff --git a/library/std/src/net/tcp.rs b/library/std/src/net/tcp.rs index ac09a805975ef..3982d3636614e 100644 --- a/library/std/src/net/tcp.rs +++ b/library/std/src/net/tcp.rs @@ -6,7 +6,7 @@ mod tests; use crate::io::prelude::*; use crate::fmt; -use crate::io::{self, IoSlice, IoSliceMut}; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::iter::FusedIterator; use crate::net::{Shutdown, SocketAddr, ToSocketAddrs}; use crate::sys_common::net as net_imp; @@ -619,6 +619,10 @@ impl Read for TcpStream { self.0.read(buf) } + fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { + self.0.read_buf(buf) + } + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { self.0.read_vectored(bufs) } @@ -653,6 +657,10 @@ impl Read for &TcpStream { self.0.read(buf) } + fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { + self.0.read_buf(buf) + } + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { self.0.read_vectored(bufs) } diff --git a/library/std/src/net/tcp/tests.rs b/library/std/src/net/tcp/tests.rs index 8c0adcfb0ebbb..b8cfead19d7ee 100644 --- a/library/std/src/net/tcp/tests.rs +++ b/library/std/src/net/tcp/tests.rs @@ -1,6 +1,7 @@ use crate::fmt; use crate::io::prelude::*; -use crate::io::{ErrorKind, IoSlice, IoSliceMut}; +use crate::io::{BorrowedBuf, ErrorKind, IoSlice, IoSliceMut}; +use crate::mem::MaybeUninit; use crate::net::test::{next_test_ip4, next_test_ip6}; use crate::net::*; use crate::sync::mpsc::channel; @@ -279,6 +280,27 @@ fn partial_read() { }) } +#[test] +fn read_buf() { + each_ip(&mut |addr| { + let srv = t!(TcpListener::bind(&addr)); + let t = thread::spawn(move || { + let mut s = t!(TcpStream::connect(&addr)); + s.write_all(&[1, 2, 3, 4]).unwrap(); + }); + + let mut s = t!(srv.accept()).0; + let mut buf: [MaybeUninit<u8>; 128] = MaybeUninit::uninit_array(); + let mut buf = BorrowedBuf::from(buf.as_mut_slice()); + t!(s.read_buf(buf.unfilled())); + assert_eq!(buf.filled(), &[1, 2, 3, 4]); + // TcpStream::read_buf should omit buffer initialization. + assert_eq!(buf.init_len(), 4); + + t.join().ok().expect("thread panicked"); + }) +} + #[test] fn read_vectored() { each_ip(&mut |addr| { diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 62ce2cb33dc55..27116f4b6139b 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -110,7 +110,7 @@ use crate::convert::Infallible; use crate::ffi::OsStr; use crate::fmt; use crate::fs; -use crate::io::{self, IoSlice, IoSliceMut}; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::num::NonZeroI32; use crate::path::Path; use crate::str; @@ -354,6 +354,10 @@ impl Read for ChildStdout { self.inner.read(buf) } + fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { + self.inner.read_buf(buf) + } + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { self.inner.read_vectored(bufs) } @@ -419,6 +423,10 @@ impl Read for ChildStderr { self.inner.read(buf) } + fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { + self.inner.read_buf(buf) + } + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { self.inner.read_vectored(bufs) } diff --git a/library/std/src/process/tests.rs b/library/std/src/process/tests.rs index b4f6cc2dabae3..0e3494e53d24b 100644 --- a/library/std/src/process/tests.rs +++ b/library/std/src/process/tests.rs @@ -1,7 +1,8 @@ use crate::io::prelude::*; use super::{Command, Output, Stdio}; -use crate::io::ErrorKind; +use crate::io::{BorrowedBuf, ErrorKind}; +use crate::mem::MaybeUninit; use crate::str; fn known_command() -> Command { @@ -119,6 +120,34 @@ fn stdin_works() { assert_eq!(out, "foobar\n"); } +#[test] +#[cfg_attr(any(target_os = "vxworks"), ignore)] +fn child_stdout_read_buf() { + let mut cmd = shell_cmd(); + if cfg!(target_os = "windows") { + cmd.arg("/C").arg("echo abc"); + } else { + cmd.arg("-c").arg("echo abc"); + }; + cmd.stdin(Stdio::null()); + cmd.stdout(Stdio::piped()); + let child = cmd.spawn().unwrap(); + + let mut stdout = child.stdout.unwrap(); + let mut buf: [MaybeUninit<u8>; 128] = MaybeUninit::uninit_array(); + let mut buf = BorrowedBuf::from(buf.as_mut_slice()); + stdout.read_buf(buf.unfilled()).unwrap(); + + // ChildStdout::read_buf should omit buffer initialization. + if cfg!(target_os = "windows") { + assert_eq!(buf.filled(), b"abc\r\n"); + assert_eq!(buf.init_len(), 5); + } else { + assert_eq!(buf.filled(), b"abc\n"); + assert_eq!(buf.init_len(), 4); + }; +} + #[test] #[cfg_attr(any(target_os = "vxworks"), ignore)] fn test_process_status() { diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs index 66c33d58d6ca3..4798992c6b07c 100644 --- a/library/std/src/sys/unix/fd.rs +++ b/library/std/src/sys/unix/fd.rs @@ -283,6 +283,15 @@ impl<'a> Read for &'a FileDesc { fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> { (**self).read_buf(cursor) } + + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { + (**self).read_vectored(bufs) + } + + #[inline] + fn is_read_vectored(&self) -> bool { + (**self).is_read_vectored() + } } impl AsInner<OwnedFd> for FileDesc { diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs index c86f80972a69d..58431a479f045 100644 --- a/library/std/src/sys/unix/net.rs +++ b/library/std/src/sys/unix/net.rs @@ -1,6 +1,6 @@ use crate::cmp; use crate::ffi::CStr; -use crate::io::{self, IoSlice, IoSliceMut}; +use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut}; use crate::mem; use crate::net::{Shutdown, SocketAddr}; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; @@ -240,19 +240,35 @@ impl Socket { self.0.duplicate().map(Socket) } - fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result<usize> { + fn recv_with_flags(&self, mut buf: BorrowedCursor<'_>, flags: c_int) -> io::Result<()> { let ret = cvt(unsafe { - libc::recv(self.as_raw_fd(), buf.as_mut_ptr() as *mut c_void, buf.len(), flags) + libc::recv( + self.as_raw_fd(), + buf.as_mut().as_mut_ptr() as *mut c_void, + buf.capacity(), + flags, + ) })?; - Ok(ret as usize) + unsafe { + buf.advance(ret as usize); + } + Ok(()) } pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - self.recv_with_flags(buf, 0) + let mut buf = BorrowedBuf::from(buf); + self.recv_with_flags(buf.unfilled(), 0)?; + Ok(buf.len()) } pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { - self.recv_with_flags(buf, MSG_PEEK) + let mut buf = BorrowedBuf::from(buf); + self.recv_with_flags(buf.unfilled(), MSG_PEEK)?; + Ok(buf.len()) + } + + pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> { + self.recv_with_flags(buf, 0) } pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { diff --git a/library/std/src/sys/unix/pipe.rs b/library/std/src/sys/unix/pipe.rs index a744d0ab64043..dc17c9fac460a 100644 --- a/library/std/src/sys/unix/pipe.rs +++ b/library/std/src/sys/unix/pipe.rs @@ -1,4 +1,4 @@ -use crate::io::{self, IoSlice, IoSliceMut}; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::mem; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; use crate::sys::fd::FileDesc; @@ -49,6 +49,10 @@ impl AnonPipe { self.0.read(buf) } + pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> { + self.0.read_buf(buf) + } + pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { self.0.read_vectored(bufs) } diff --git a/library/std/src/sys/unix/stdio.rs b/library/std/src/sys/unix/stdio.rs index b3626c564e86a..a26f20795a191 100644 --- a/library/std/src/sys/unix/stdio.rs +++ b/library/std/src/sys/unix/stdio.rs @@ -1,4 +1,4 @@ -use crate::io::{self, IoSlice, IoSliceMut}; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::mem::ManuallyDrop; use crate::os::unix::io::FromRawFd; use crate::sys::fd::FileDesc; @@ -18,6 +18,10 @@ impl io::Read for Stdin { unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDIN_FILENO)).read(buf) } } + fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { + unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDIN_FILENO)).read_buf(buf) } + } + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { unsafe { ManuallyDrop::new(FileDesc::from_raw_fd(libc::STDIN_FILENO)).read_vectored(bufs) } } diff --git a/library/std/src/sys/unsupported/pipe.rs b/library/std/src/sys/unsupported/pipe.rs index 0bba673b458cb..d7d8f297ae586 100644 --- a/library/std/src/sys/unsupported/pipe.rs +++ b/library/std/src/sys/unsupported/pipe.rs @@ -1,4 +1,4 @@ -use crate::io::{self, IoSlice, IoSliceMut}; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; pub struct AnonPipe(!); @@ -7,6 +7,10 @@ impl AnonPipe { self.0 } + pub fn read_buf(&self, _buf: BorrowedCursor<'_>) -> io::Result<()> { + self.0 + } + pub fn read_vectored(&self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { self.0 } diff --git a/library/std/src/sys/windows/handle.rs b/library/std/src/sys/windows/handle.rs index ae33d48c612ee..b290f4070e8fd 100644 --- a/library/std/src/sys/windows/handle.rs +++ b/library/std/src/sys/windows/handle.rs @@ -327,7 +327,16 @@ impl<'a> Read for &'a Handle { (**self).read(buf) } + fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { + (**self).read_buf(buf) + } + fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { (**self).read_vectored(bufs) } + + #[inline] + fn is_read_vectored(&self) -> bool { + (**self).is_read_vectored() + } } diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs index e0701a498fad7..ee1f5482b47ee 100644 --- a/library/std/src/sys/windows/net.rs +++ b/library/std/src/sys/windows/net.rs @@ -1,7 +1,7 @@ #![unstable(issue = "none", feature = "windows_net")] use crate::cmp; -use crate::io::{self, IoSlice, IoSliceMut, Read}; +use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut, Read}; use crate::mem; use crate::net::{Shutdown, SocketAddr}; use crate::os::windows::io::{ @@ -214,28 +214,38 @@ impl Socket { Ok(Self(self.0.try_clone()?)) } - fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result<usize> { + fn recv_with_flags(&self, mut buf: BorrowedCursor<'_>, flags: c_int) -> io::Result<()> { // On unix when a socket is shut down all further reads return 0, so we // do the same on windows to map a shut down socket to returning EOF. - let length = cmp::min(buf.len(), i32::MAX as usize) as i32; - let result = - unsafe { c::recv(self.as_raw_socket(), buf.as_mut_ptr() as *mut _, length, flags) }; + let length = cmp::min(buf.capacity(), i32::MAX as usize) as i32; + let result = unsafe { + c::recv(self.as_raw_socket(), buf.as_mut().as_mut_ptr() as *mut _, length, flags) + }; match result { c::SOCKET_ERROR => { let error = unsafe { c::WSAGetLastError() }; if error == c::WSAESHUTDOWN { - Ok(0) + Ok(()) } else { Err(io::Error::from_raw_os_error(error)) } } - _ => Ok(result as usize), + _ => { + unsafe { buf.advance(result as usize) }; + Ok(()) + } } } pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { + let mut buf = BorrowedBuf::from(buf); + self.recv_with_flags(buf.unfilled(), 0)?; + Ok(buf.len()) + } + + pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> { self.recv_with_flags(buf, 0) } @@ -277,7 +287,9 @@ impl Socket { } pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { - self.recv_with_flags(buf, c::MSG_PEEK) + let mut buf = BorrowedBuf::from(buf); + self.recv_with_flags(buf.unfilled(), c::MSG_PEEK)?; + Ok(buf.len()) } fn recv_from_with_flags( diff --git a/library/std/src/sys/windows/pipe.rs b/library/std/src/sys/windows/pipe.rs index 7b25edaa556f0..0780b29584da4 100644 --- a/library/std/src/sys/windows/pipe.rs +++ b/library/std/src/sys/windows/pipe.rs @@ -1,7 +1,7 @@ use crate::os::windows::prelude::*; use crate::ffi::OsStr; -use crate::io::{self, IoSlice, IoSliceMut, Read}; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read}; use crate::mem; use crate::path::Path; use crate::ptr; @@ -252,6 +252,28 @@ impl AnonPipe { } } + pub fn read_buf(&self, mut buf: BorrowedCursor<'_>) -> io::Result<()> { + let result = unsafe { + let len = crate::cmp::min(buf.capacity(), c::DWORD::MAX as usize) as c::DWORD; + self.alertable_io_internal(c::ReadFileEx, buf.as_mut().as_mut_ptr() as _, len) + }; + + match result { + // The special treatment of BrokenPipe is to deal with Windows + // pipe semantics, which yields this error when *reading* from + // a pipe after the other end has closed; we interpret that as + // EOF on the pipe. + Err(ref e) if e.kind() == io::ErrorKind::BrokenPipe => Ok(()), + Err(e) => Err(e), + Ok(n) => { + unsafe { + buf.advance(n); + } + Ok(()) + } + } + } + pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { self.inner.read_vectored(bufs) } diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs index 2c38dfecf9734..ab988b97193c4 100644 --- a/library/std/src/sys_common/net.rs +++ b/library/std/src/sys_common/net.rs @@ -4,7 +4,7 @@ mod tests; use crate::cmp; use crate::convert::{TryFrom, TryInto}; use crate::fmt; -use crate::io::{self, ErrorKind, IoSlice, IoSliceMut}; +use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut}; use crate::mem; use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr}; use crate::ptr; @@ -271,6 +271,10 @@ impl TcpStream { self.inner.read(buf) } + pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> { + self.inner.read_buf(buf) + } + pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { self.inner.read_vectored(bufs) } From 506ce7e3cc5637bd5832bbb3d1f3ba3725797477 Mon Sep 17 00:00:00 2001 From: Michael Goulet <michael@errs.io> Date: Wed, 22 Feb 2023 22:13:52 +0000 Subject: [PATCH 3/7] Re-apply "switch to the macos-12-xl builder" This reverts commit e63ec2e1402eaff949e5c53b8f6062b152010fcc. --- .github/workflows/ci.yml | 12 ++++++------ src/ci/github-actions/ci.yml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c17dfd8c8edc..44f789c592ba2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -322,7 +322,7 @@ jobs: NO_DEBUG_ASSERTIONS: 1 NO_OVERFLOW_CHECKS: 1 DIST_REQUIRE_ALL_TOOLS: 1 - os: macos-latest + os: macos-12-xl - name: dist-apple-various env: SCRIPT: "./x.py dist bootstrap --include-default-paths --host='' --target=aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim" @@ -333,7 +333,7 @@ jobs: NO_LLVM_ASSERTIONS: 1 NO_DEBUG_ASSERTIONS: 1 NO_OVERFLOW_CHECKS: 1 - os: macos-latest + os: macos-12-xl - name: dist-x86_64-apple-alt env: SCRIPT: "./x.py dist bootstrap --include-default-paths" @@ -344,7 +344,7 @@ jobs: NO_LLVM_ASSERTIONS: 1 NO_DEBUG_ASSERTIONS: 1 NO_OVERFLOW_CHECKS: 1 - os: macos-latest + os: macos-12-xl - name: x86_64-apple-1 env: SCRIPT: "./x.py --stage 2 test --exclude tests/ui --exclude tests/rustdoc --exclude tests/run-make-fulldeps" @@ -355,7 +355,7 @@ jobs: NO_LLVM_ASSERTIONS: 1 NO_DEBUG_ASSERTIONS: 1 NO_OVERFLOW_CHECKS: 1 - os: macos-latest + os: macos-12-xl - name: x86_64-apple-2 env: SCRIPT: "./x.py --stage 2 test tests/ui tests/rustdoc tests/run-make-fulldeps" @@ -366,7 +366,7 @@ jobs: NO_LLVM_ASSERTIONS: 1 NO_DEBUG_ASSERTIONS: 1 NO_OVERFLOW_CHECKS: 1 - os: macos-latest + os: macos-12-xl - name: dist-aarch64-apple env: SCRIPT: "./x.py dist bootstrap --include-default-paths --stage 2" @@ -381,7 +381,7 @@ jobs: NO_OVERFLOW_CHECKS: 1 DIST_REQUIRE_ALL_TOOLS: 1 JEMALLOC_SYS_WITH_LG_PAGE: 14 - os: macos-latest + os: macos-12-xl - name: x86_64-msvc-1 env: RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-profiler" diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index ad9c308ad852d..11f1532bef594 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -78,7 +78,7 @@ x--expand-yaml-anchors--remove: <<: *base-job - &job-macos-xl - os: macos-latest # We don't have an XL builder for this + os: macos-12-xl <<: *base-job - &job-windows-xl From 11fbb573951d61b7de9b773750c206253a5db974 Mon Sep 17 00:00:00 2001 From: Camille GILLOT <gillot.camille@gmail.com> Date: Tue, 25 Oct 2022 18:34:58 +0000 Subject: [PATCH 4/7] Simplify diagnostic_items. --- compiler/rustc_middle/src/hir/mod.rs | 14 +++-- compiler/rustc_passes/src/diagnostic_items.rs | 63 +++++++++---------- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 2e2ca6a27888e..ad119c4e07306 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -64,13 +64,17 @@ impl ModuleItems { self.foreign_items.iter().copied() } - pub fn definitions(&self) -> impl Iterator<Item = LocalDefId> + '_ { + pub fn owners(&self) -> impl Iterator<Item = OwnerId> + '_ { self.items .iter() - .map(|id| id.owner_id.def_id) - .chain(self.trait_items.iter().map(|id| id.owner_id.def_id)) - .chain(self.impl_items.iter().map(|id| id.owner_id.def_id)) - .chain(self.foreign_items.iter().map(|id| id.owner_id.def_id)) + .map(|id| id.owner_id) + .chain(self.trait_items.iter().map(|id| id.owner_id)) + .chain(self.impl_items.iter().map(|id| id.owner_id)) + .chain(self.foreign_items.iter().map(|id| id.owner_id)) + } + + pub fn definitions(&self) -> impl Iterator<Item = LocalDefId> + '_ { + self.owners().map(|id| id.def_id) } pub fn par_items(&self, f: impl Fn(ItemId) + Send + Sync) { diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index 0ae7096642cf1..ae3d40b0ec516 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -11,19 +11,19 @@ use rustc_ast as ast; use rustc_hir::diagnostic_items::DiagnosticItems; +use rustc_hir::OwnerId; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; -use rustc_span::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; +use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_span::symbol::{kw::Empty, sym, Symbol}; use crate::errors::{DuplicateDiagnosticItem, DuplicateDiagnosticItemInCrate}; -fn observe_item(tcx: TyCtxt<'_>, diagnostic_items: &mut DiagnosticItems, def_id: LocalDefId) { - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - let attrs = tcx.hir().attrs(hir_id); +fn observe_item<'tcx>(tcx: TyCtxt<'tcx>, diagnostic_items: &mut DiagnosticItems, owner: OwnerId) { + let attrs = tcx.hir().attrs(owner.into()); if let Some(name) = extract(attrs) { // insert into our table - collect_item(tcx, diagnostic_items, name, def_id.to_def_id()); + collect_item(tcx, diagnostic_items, name, owner.to_def_id()); } } @@ -31,23 +31,33 @@ fn collect_item(tcx: TyCtxt<'_>, items: &mut DiagnosticItems, name: Symbol, item items.id_to_name.insert(item_def_id, name); if let Some(original_def_id) = items.name_to_id.insert(name, item_def_id) { if original_def_id != item_def_id { - let orig_span = tcx.hir().span_if_local(original_def_id); - let orig_crate_name = - orig_span.is_none().then(|| tcx.crate_name(original_def_id.krate)); - match tcx.hir().span_if_local(item_def_id) { - Some(span) => tcx.sess.emit_err(DuplicateDiagnosticItem { span, name }), - None => tcx.sess.emit_err(DuplicateDiagnosticItemInCrate { - span: orig_span, - orig_crate_name: orig_crate_name.unwrap_or(Empty), - have_orig_crate_name: orig_crate_name.map(|_| ()), - crate_name: tcx.crate_name(item_def_id.krate), - name, - }), - }; + report_duplicate_item(tcx, name, original_def_id, item_def_id); } } } +fn report_duplicate_item( + tcx: TyCtxt<'_>, + name: Symbol, + original_def_id: DefId, + item_def_id: DefId, +) { + let (orig_span, orig_crate_name, have_orig_crate_name) = match original_def_id.as_local() { + Some(local_original) => (Some(tcx.def_span(local_original)), Empty, None), + None => (None, tcx.crate_name(original_def_id.krate), Some(())), + }; + match tcx.hir().span_if_local(item_def_id) { + Some(span) => tcx.sess.emit_err(DuplicateDiagnosticItem { span, name }), + None => tcx.sess.emit_err(DuplicateDiagnosticItemInCrate { + span: orig_span, + orig_crate_name, + have_orig_crate_name, + crate_name: tcx.crate_name(item_def_id.krate), + name, + }), + }; +} + /// Extract the first `rustc_diagnostic_item = "$name"` out of a list of attributes. fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> { attrs.iter().find_map(|attr| { @@ -64,21 +74,8 @@ fn diagnostic_items(tcx: TyCtxt<'_>, cnum: CrateNum) -> DiagnosticItems { // Collect diagnostic items in this crate. let crate_items = tcx.hir_crate_items(()); - - for id in crate_items.items() { - observe_item(tcx, &mut diagnostic_items, id.owner_id.def_id); - } - - for id in crate_items.trait_items() { - observe_item(tcx, &mut diagnostic_items, id.owner_id.def_id); - } - - for id in crate_items.impl_items() { - observe_item(tcx, &mut diagnostic_items, id.owner_id.def_id); - } - - for id in crate_items.foreign_items() { - observe_item(tcx, &mut diagnostic_items, id.owner_id.def_id); + for id in crate_items.owners() { + observe_item(tcx, &mut diagnostic_items, id); } diagnostic_items From 752ddd028c877c2033940d0dcd4e3dcbf569ae9d Mon Sep 17 00:00:00 2001 From: Camille GILLOT <gillot.camille@gmail.com> Date: Sun, 26 Feb 2023 10:29:25 +0000 Subject: [PATCH 5/7] Merge the two diagnostics. --- compiler/rustc_passes/locales/en-US.ftl | 3 -- compiler/rustc_passes/src/diagnostic_items.rs | 28 ++++++++----------- compiler/rustc_passes/src/errors.rs | 16 ++++------- .../tool-attributes/duplicate-diagnostic.rs | 2 +- .../duplicate-diagnostic.stderr | 4 ++- 5 files changed, 21 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_passes/locales/en-US.ftl b/compiler/rustc_passes/locales/en-US.ftl index 0ed29ce0d4795..3fa78efc290ba 100644 --- a/compiler/rustc_passes/locales/en-US.ftl +++ b/compiler/rustc_passes/locales/en-US.ftl @@ -402,9 +402,6 @@ passes_invalid_attr_at_crate_level = `{$name}` attribute cannot be used at crate level .suggestion = perhaps you meant to use an outer attribute -passes_duplicate_diagnostic_item = - duplicate diagnostic item found: `{$name}`. - passes_duplicate_diagnostic_item_in_crate = duplicate diagnostic item in crate `{$crate_name}`: `{$name}`. .note = the diagnostic item is first defined in crate `{$orig_crate_name}`. diff --git a/compiler/rustc_passes/src/diagnostic_items.rs b/compiler/rustc_passes/src/diagnostic_items.rs index ae3d40b0ec516..110eb210df9ad 100644 --- a/compiler/rustc_passes/src/diagnostic_items.rs +++ b/compiler/rustc_passes/src/diagnostic_items.rs @@ -15,9 +15,9 @@ use rustc_hir::OwnerId; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; -use rustc_span::symbol::{kw::Empty, sym, Symbol}; +use rustc_span::symbol::{sym, Symbol}; -use crate::errors::{DuplicateDiagnosticItem, DuplicateDiagnosticItemInCrate}; +use crate::errors::DuplicateDiagnosticItemInCrate; fn observe_item<'tcx>(tcx: TyCtxt<'tcx>, diagnostic_items: &mut DiagnosticItems, owner: OwnerId) { let attrs = tcx.hir().attrs(owner.into()); @@ -42,20 +42,16 @@ fn report_duplicate_item( original_def_id: DefId, item_def_id: DefId, ) { - let (orig_span, orig_crate_name, have_orig_crate_name) = match original_def_id.as_local() { - Some(local_original) => (Some(tcx.def_span(local_original)), Empty, None), - None => (None, tcx.crate_name(original_def_id.krate), Some(())), - }; - match tcx.hir().span_if_local(item_def_id) { - Some(span) => tcx.sess.emit_err(DuplicateDiagnosticItem { span, name }), - None => tcx.sess.emit_err(DuplicateDiagnosticItemInCrate { - span: orig_span, - orig_crate_name, - have_orig_crate_name, - crate_name: tcx.crate_name(item_def_id.krate), - name, - }), - }; + let orig_span = tcx.hir().span_if_local(original_def_id); + let duplicate_span = tcx.hir().span_if_local(item_def_id); + tcx.sess.emit_err(DuplicateDiagnosticItemInCrate { + duplicate_span, + orig_span, + crate_name: tcx.crate_name(item_def_id.krate), + orig_crate_name: tcx.crate_name(original_def_id.krate), + different_crates: (item_def_id.krate != original_def_id.krate).then_some(()), + name, + }); } /// Extract the first `rustc_diagnostic_item = "$name"` out of a list of attributes. diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 2c0d21b479848..9f1c0b5a0b7bd 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -809,23 +809,17 @@ impl IntoDiagnostic<'_> for InvalidAttrAtCrateLevel { } } -#[derive(Diagnostic)] -#[diag(passes_duplicate_diagnostic_item)] -pub struct DuplicateDiagnosticItem { - #[primary_span] - pub span: Span, - pub name: Symbol, -} - #[derive(Diagnostic)] #[diag(passes_duplicate_diagnostic_item_in_crate)] pub struct DuplicateDiagnosticItemInCrate { + #[primary_span] + pub duplicate_span: Option<Span>, #[note(passes_diagnostic_item_first_defined)] - pub span: Option<Span>, - pub orig_crate_name: Symbol, + pub orig_span: Option<Span>, #[note] - pub have_orig_crate_name: Option<()>, + pub different_crates: Option<()>, pub crate_name: Symbol, + pub orig_crate_name: Symbol, pub name: Symbol, } diff --git a/tests/ui/tool-attributes/duplicate-diagnostic.rs b/tests/ui/tool-attributes/duplicate-diagnostic.rs index 39c2ca1cb860c..e2cf9508757be 100644 --- a/tests/ui/tool-attributes/duplicate-diagnostic.rs +++ b/tests/ui/tool-attributes/duplicate-diagnostic.rs @@ -9,5 +9,5 @@ extern crate p1; extern crate p2; #[rustc_diagnostic_item = "Foo"] -pub struct Foo {} //~ ERROR duplicate diagnostic item found +pub struct Foo {} //~ ERROR duplicate diagnostic item in crate `duplicate_diagnostic`: `Foo` fn main() {} diff --git a/tests/ui/tool-attributes/duplicate-diagnostic.stderr b/tests/ui/tool-attributes/duplicate-diagnostic.stderr index e315fdc7d84bc..26bd6a82e3417 100644 --- a/tests/ui/tool-attributes/duplicate-diagnostic.stderr +++ b/tests/ui/tool-attributes/duplicate-diagnostic.stderr @@ -2,11 +2,13 @@ error: duplicate diagnostic item in crate `p2`: `Foo`. | = note: the diagnostic item is first defined in crate `p1`. -error: duplicate diagnostic item found: `Foo`. +error: duplicate diagnostic item in crate `duplicate_diagnostic`: `Foo`. --> $DIR/duplicate-diagnostic.rs:12:1 | LL | pub struct Foo {} | ^^^^^^^^^^^^^^ + | + = note: the diagnostic item is first defined in crate `p2`. error: aborting due to 2 previous errors From 32da026c35d07e1e256421b0860d136f01ee3bf0 Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Sun, 26 Feb 2023 01:39:43 +0100 Subject: [PATCH 6/7] generalize help message --- compiler/rustc_parse/locales/en-US.ftl | 2 +- tests/ui/parser/match-arm-without-braces.stderr | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_parse/locales/en-US.ftl b/compiler/rustc_parse/locales/en-US.ftl index a31b1f6ac1a0a..4ddeeed5b7e0a 100644 --- a/compiler/rustc_parse/locales/en-US.ftl +++ b/compiler/rustc_parse/locales/en-US.ftl @@ -220,7 +220,7 @@ parse_match_arm_body_without_braces = `match` arm body without braces [one] statement *[other] statements } with a body - .suggestion_use_comma_not_semicolon = use a comma to end a `match` arm expression + .suggestion_use_comma_not_semicolon = replace `;` with `,` to end a `match` arm expression parse_inclusive_range_extra_equals = unexpected `=` after inclusive range .suggestion_remove_eq = use `..=` instead diff --git a/tests/ui/parser/match-arm-without-braces.stderr b/tests/ui/parser/match-arm-without-braces.stderr index 37d55aa53f87c..ee1c8e562fc33 100644 --- a/tests/ui/parser/match-arm-without-braces.stderr +++ b/tests/ui/parser/match-arm-without-braces.stderr @@ -2,10 +2,14 @@ error: `match` arm body without braces --> $DIR/match-arm-without-braces.rs:26:27 | LL | Some(Val::Foo) => 3; - | -- ^- help: use a comma to end a `match` arm expression: `,` - | | | - | | this statement is not surrounded by a body + | -- ^ this statement is not surrounded by a body + | | | while parsing the `match` arm starting here + | +help: replace `;` with `,` to end a `match` arm expression + | +LL | Some(Val::Foo) => 3, + | ~ error: `match` arm body without braces --> $DIR/match-arm-without-braces.rs:31:11 From 27db6882038b67d83b8aecf108b18dd350f7e7cc Mon Sep 17 00:00:00 2001 From: Guillaume Gomez <guillaume.gomez@huawei.com> Date: Sun, 26 Feb 2023 16:26:59 +0100 Subject: [PATCH 7/7] Clean up JS files code a bit --- src/librustdoc/html/static/js/search.js | 17 ++++++----------- src/librustdoc/html/static/js/source-script.js | 3 +-- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 1e6c94d29ba47..b3fc889431b38 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -463,11 +463,10 @@ function initSearch(rawSearchIndex) { * @param {ParserState} parserState */ function parseInput(query, parserState) { - let c, before; let foundStopChar = true; while (parserState.pos < parserState.length) { - c = parserState.userQuery[parserState.pos]; + const c = parserState.userQuery[parserState.pos]; if (isStopCharacter(c)) { foundStopChar = true; if (isSeparatorCharacter(c)) { @@ -506,7 +505,7 @@ function initSearch(rawSearchIndex) { } throw new Error(`Expected \`,\`, \` \`, \`:\` or \`->\`, found \`${c}\``); } - before = query.elems.length; + const before = query.elems.length; getNextElem(query, parserState, query.elems, false); if (query.elems.length === before) { // Nothing was added, weird... Let's increase the position to not remain stuck. @@ -515,7 +514,6 @@ function initSearch(rawSearchIndex) { foundStopChar = false; } while (parserState.pos < parserState.length) { - c = parserState.userQuery[parserState.pos]; if (isReturnArrow(parserState)) { parserState.pos += 2; // Get returned elements. @@ -1940,7 +1938,6 @@ function initSearch(rawSearchIndex) { */ const searchWords = []; const charA = "A".charCodeAt(0); - let i, word; let currentIndex = 0; let id = 0; @@ -2035,7 +2032,7 @@ function initSearch(rawSearchIndex) { // convert `rawPaths` entries into object form // generate normalizedPaths for function search mode let len = paths.length; - for (i = 0; i < len; ++i) { + for (let i = 0; i < len; ++i) { lowercasePaths.push({ty: paths[i][0], name: paths[i][1].toLowerCase()}); paths[i] = {ty: paths[i][0], name: paths[i][1]}; } @@ -2049,16 +2046,14 @@ function initSearch(rawSearchIndex) { // faster analysis operations len = itemTypes.length; let lastPath = ""; - for (i = 0; i < len; ++i) { + for (let i = 0; i < len; ++i) { + let word = ""; // This object should have exactly the same set of fields as the "crateRow" // object defined above. if (typeof itemNames[i] === "string") { word = itemNames[i].toLowerCase(); - searchWords.push(word); - } else { - word = ""; - searchWords.push(""); } + searchWords.push(word); const row = { crate: crate, ty: itemTypes.charCodeAt(i) - charA, diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js index 0e1c864e62d84..6c0f03b5bb072 100644 --- a/src/librustdoc/html/static/js/source-script.js +++ b/src/librustdoc/html/static/js/source-script.js @@ -117,8 +117,7 @@ function createSourceSidebar() { sidebar.appendChild(title); Object.keys(sourcesIndex).forEach(key => { sourcesIndex[key][NAME_OFFSET] = key; - hasFoundFile = createDirEntry(sourcesIndex[key], sidebar, "", - hasFoundFile); + hasFoundFile = createDirEntry(sourcesIndex[key], sidebar, "", hasFoundFile); }); container.appendChild(sidebar);