Skip to content

Commit 098ada1

Browse files
committed
Auto merge of rust-lang#130964 - matthiaskrgr:rollup-suriuub, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#125404 (Fix `read_buf` uses in `std`) - rust-lang#130866 (Allow instantiating object trait binder when upcasting) - rust-lang#130922 (Reference UNSPECIFIED instead of INADDR_ANY in join_multicast_v4) - rust-lang#130924 (Make clashing_extern_declarations considering generic args for ADT field) - rust-lang#130939 (rustdoc: update `ProcMacro` docs section on helper attributes) - rust-lang#130940 (Revert space-saving operations) - rust-lang#130944 (Allow instantiating trait object binder in ptr-to-ptr casts) - rust-lang#130953 (Rename a few tests to make tidy happier) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 9f50f5a + e66058d commit 098ada1

File tree

5 files changed

+90
-18
lines changed

5 files changed

+90
-18
lines changed

std/src/io/buffered/bufreader.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ impl<R: ?Sized + Read> Read for BufReader<R> {
357357
let prev = cursor.written();
358358

359359
let mut rem = self.fill_buf()?;
360-
rem.read_buf(cursor.reborrow())?;
360+
rem.read_buf(cursor.reborrow())?; // actually never fails
361361

362362
self.consume(cursor.written() - prev); //slice impl of read_buf known to never unfill buf
363363

std/src/io/buffered/bufreader/buffer.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,13 @@ impl Buffer {
143143
buf.set_init(self.initialized);
144144
}
145145

146-
reader.read_buf(buf.unfilled())?;
146+
let result = reader.read_buf(buf.unfilled());
147147

148148
self.pos = 0;
149149
self.filled = buf.len();
150150
self.initialized = buf.init_len();
151+
152+
result?;
151153
}
152154
Ok(self.buffer())
153155
}

std/src/io/mod.rs

+21-14
Original file line numberDiff line numberDiff line change
@@ -474,18 +474,28 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
474474
}
475475

476476
let mut cursor = read_buf.unfilled();
477-
loop {
477+
let result = loop {
478478
match r.read_buf(cursor.reborrow()) {
479-
Ok(()) => break,
480479
Err(e) if e.is_interrupted() => continue,
481-
Err(e) => return Err(e),
480+
// Do not stop now in case of error: we might have received both data
481+
// and an error
482+
res => break res,
482483
}
483-
}
484+
};
484485

485486
let unfilled_but_initialized = cursor.init_ref().len();
486487
let bytes_read = cursor.written();
487488
let was_fully_initialized = read_buf.init_len() == buf_len;
488489

490+
// SAFETY: BorrowedBuf's invariants mean this much memory is initialized.
491+
unsafe {
492+
let new_len = bytes_read + buf.len();
493+
buf.set_len(new_len);
494+
}
495+
496+
// Now that all data is pushed to the vector, we can fail without data loss
497+
result?;
498+
489499
if bytes_read == 0 {
490500
return Ok(buf.len() - start_len);
491501
}
@@ -499,12 +509,6 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(
499509
// store how much was initialized but not filled
500510
initialized = unfilled_but_initialized;
501511

502-
// SAFETY: BorrowedBuf's invariants mean this much memory is initialized.
503-
unsafe {
504-
let new_len = bytes_read + buf.len();
505-
buf.set_len(new_len);
506-
}
507-
508512
// Use heuristics to determine the max read size if no initial size hint was provided
509513
if size_hint.is_none() {
510514
// The reader is returning short reads but it doesn't call ensure_init().
@@ -974,6 +978,8 @@ pub trait Read {
974978
/// with uninitialized buffers. The new data will be appended to any existing contents of `buf`.
975979
///
976980
/// The default implementation delegates to `read`.
981+
///
982+
/// This method makes it possible to return both data and an error but it is advised against.
977983
#[unstable(feature = "read_buf", issue = "78485")]
978984
fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<()> {
979985
default_read_buf(|b| self.read(b), buf)
@@ -2941,7 +2947,7 @@ impl<T: Read> Read for Take<T> {
29412947
}
29422948

29432949
let mut cursor = sliced_buf.unfilled();
2944-
self.inner.read_buf(cursor.reborrow())?;
2950+
let result = self.inner.read_buf(cursor.reborrow());
29452951

29462952
let new_init = cursor.init_ref().len();
29472953
let filled = sliced_buf.len();
@@ -2956,13 +2962,14 @@ impl<T: Read> Read for Take<T> {
29562962
}
29572963

29582964
self.limit -= filled as u64;
2965+
2966+
result
29592967
} else {
29602968
let written = buf.written();
2961-
self.inner.read_buf(buf.reborrow())?;
2969+
let result = self.inner.read_buf(buf.reborrow());
29622970
self.limit -= (buf.written() - written) as u64;
2971+
result
29632972
}
2964-
2965-
Ok(())
29662973
}
29672974
}
29682975

std/src/io/tests.rs

+63
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,69 @@ fn read_buf_full_read() {
735735
assert_eq!(BufReader::new(FullRead).fill_buf().unwrap().len(), DEFAULT_BUF_SIZE);
736736
}
737737

738+
struct DataAndErrorReader(&'static [u8]);
739+
740+
impl Read for DataAndErrorReader {
741+
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
742+
panic!("We want tests to use `read_buf`")
743+
}
744+
745+
fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> {
746+
self.0.read_buf(buf).unwrap();
747+
Err(io::Error::other("error"))
748+
}
749+
}
750+
751+
#[test]
752+
fn read_buf_data_and_error_take() {
753+
let mut buf = [0; 64];
754+
let mut buf = io::BorrowedBuf::from(buf.as_mut_slice());
755+
756+
let mut r = DataAndErrorReader(&[4, 5, 6]).take(1);
757+
assert!(r.read_buf(buf.unfilled()).is_err());
758+
assert_eq!(buf.filled(), &[4]);
759+
760+
assert!(r.read_buf(buf.unfilled()).is_ok());
761+
assert_eq!(buf.filled(), &[4]);
762+
assert_eq!(r.get_ref().0, &[5, 6]);
763+
}
764+
765+
#[test]
766+
fn read_buf_data_and_error_buf() {
767+
let mut r = BufReader::new(DataAndErrorReader(&[4, 5, 6]));
768+
769+
assert!(r.fill_buf().is_err());
770+
assert_eq!(r.fill_buf().unwrap(), &[4, 5, 6]);
771+
}
772+
773+
#[test]
774+
fn read_buf_data_and_error_read_to_end() {
775+
let mut r = DataAndErrorReader(&[4, 5, 6]);
776+
777+
let mut v = Vec::with_capacity(200);
778+
assert!(r.read_to_end(&mut v).is_err());
779+
780+
assert_eq!(v, &[4, 5, 6]);
781+
}
782+
783+
#[test]
784+
fn read_to_end_error() {
785+
struct ErrorReader;
786+
787+
impl Read for ErrorReader {
788+
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
789+
Err(io::Error::other("error"))
790+
}
791+
}
792+
793+
let mut r = [4, 5, 6].chain(ErrorReader);
794+
795+
let mut v = Vec::with_capacity(200);
796+
assert!(r.read_to_end(&mut v).is_err());
797+
798+
assert_eq!(v, &[4, 5, 6]);
799+
}
800+
738801
#[test]
739802
// Miri does not support signalling OOM
740803
#[cfg_attr(miri, ignore)]

std/src/net/udp.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -579,8 +579,8 @@ impl UdpSocket {
579579
/// This function specifies a new multicast group for this socket to join.
580580
/// The address must be a valid multicast address, and `interface` is the
581581
/// address of the local interface with which the system should join the
582-
/// multicast group. If it's equal to `INADDR_ANY` then an appropriate
583-
/// interface is chosen by the system.
582+
/// multicast group. If it's equal to [`UNSPECIFIED`](Ipv4Addr::UNSPECIFIED)
583+
/// then an appropriate interface is chosen by the system.
584584
#[stable(feature = "net2_mutators", since = "1.9.0")]
585585
pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
586586
self.0.join_multicast_v4(multiaddr, interface)

0 commit comments

Comments
 (0)