diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 3fa965d08e698..5bb178fc441f3 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1085,6 +1085,10 @@ impl<'a> IoSliceMut<'a> { /// Also see [`IoSliceMut::advance_slices`] to advance the cursors of /// multiple buffers. /// + /// # Panics + /// + /// Panics when trying to advance beyond the end of the slice. + /// /// # Examples /// /// ``` @@ -1106,15 +1110,18 @@ impl<'a> IoSliceMut<'a> { self.0.advance(n) } - /// Advance the internal cursor of the slices. + /// Advance a slice of slices. /// - /// # Notes + /// Shrinks the slice to remove any `IoSliceMut`s that are fully advanced over. + /// If the cursor ends up in the middle of an `IoSliceMut`, it is modified + /// to start at that cursor. /// - /// Elements in the slice may be modified if the cursor is not advanced to - /// the end of the slice. For example if we have a slice of buffers with 2 - /// `IoSliceMut`s, both of length 8, and we advance the cursor by 10 bytes - /// the first `IoSliceMut` will be untouched however the second will be - /// modified to remove the first 2 bytes (10 - 8). + /// For example, if we have a slice of two 8-byte `IoSliceMut`s, and we advance by 10 bytes, + /// the result will only include the second `IoSliceMut`, advanced by 2 bytes. + /// + /// # Panics + /// + /// Panics when trying to advance beyond the end of the slices. /// /// # Examples /// @@ -1155,7 +1162,9 @@ impl<'a> IoSliceMut<'a> { } *bufs = &mut replace(bufs, &mut [])[remove..]; - if !bufs.is_empty() { + if bufs.is_empty() { + assert!(n == accumulated_len, "advancing io slices beyond their length"); + } else { bufs[0].advance(n - accumulated_len) } } @@ -1220,6 +1229,10 @@ impl<'a> IoSlice<'a> { /// Also see [`IoSlice::advance_slices`] to advance the cursors of multiple /// buffers. /// + /// # Panics + /// + /// Panics when trying to advance beyond the end of the slice. + /// /// # Examples /// /// ``` @@ -1241,15 +1254,18 @@ impl<'a> IoSlice<'a> { self.0.advance(n) } - /// Advance the internal cursor of the slices. + /// Advance a slice of slices. /// - /// # Notes + /// Shrinks the slice to remove any `IoSlice`s that are fully advanced over. + /// If the cursor ends up in the middle of an `IoSlice`, it is modified + /// to start at that cursor. /// - /// Elements in the slice may be modified if the cursor is not advanced to - /// the end of the slice. For example if we have a slice of buffers with 2 - /// `IoSlice`s, both of length 8, and we advance the cursor by 10 bytes the - /// first `IoSlice` will be untouched however the second will be modified to - /// remove the first 2 bytes (10 - 8). + /// For example, if we have a slice of two 8-byte `IoSlice`s, and we advance by 10 bytes, + /// the result will only include the second `IoSlice`, advanced by 2 bytes. + /// + /// # Panics + /// + /// Panics when trying to advance beyond the end of the slices. /// /// # Examples /// @@ -1289,7 +1305,9 @@ impl<'a> IoSlice<'a> { } *bufs = &mut replace(bufs, &mut [])[remove..]; - if !bufs.is_empty() { + if bufs.is_empty() { + assert!(n == accumulated_len, "advancing io slices beyond their length"); + } else { bufs[0].advance(n - accumulated_len) } } diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs index eb62634856462..d5a8c93b0ce9f 100644 --- a/library/std/src/io/tests.rs +++ b/library/std/src/io/tests.rs @@ -423,18 +423,18 @@ fn io_slice_mut_advance_slices() { } #[test] +#[should_panic] fn io_slice_mut_advance_slices_empty_slice() { let mut empty_bufs = &mut [][..]; - // Shouldn't panic. IoSliceMut::advance_slices(&mut empty_bufs, 1); } #[test] +#[should_panic] fn io_slice_mut_advance_slices_beyond_total_length() { let mut buf1 = [1; 8]; let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..]; - // Going beyond the total length should be ok. IoSliceMut::advance_slices(&mut bufs, 9); assert!(bufs.is_empty()); } @@ -463,18 +463,18 @@ fn io_slice_advance_slices() { } #[test] +#[should_panic] fn io_slice_advance_slices_empty_slice() { let mut empty_bufs = &mut [][..]; - // Shouldn't panic. IoSlice::advance_slices(&mut empty_bufs, 1); } #[test] +#[should_panic] fn io_slice_advance_slices_beyond_total_length() { let buf1 = [1; 8]; let mut bufs = &mut [IoSlice::new(&buf1)][..]; - // Going beyond the total length should be ok. IoSlice::advance_slices(&mut bufs, 9); assert!(bufs.is_empty()); }