@@ -1631,27 +1631,33 @@ impl<'a> Deref for IoSlice<'a> {
16311631///
16321632/// When the slice contains over `n` buffers, ensure that at least one non-empty
16331633/// buffer is in the truncated slice, if there is one.
1634+ ///
1635+ /// For example, [POSIX writev] requires that `bufs.len()` is in `1..=IOV_MAX`.
1636+ ///
1637+ /// [POSIX writev]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/writev.html
16341638#[ allow( unused_macros) ] // Not used on all platforms
1635- pub ( crate ) macro limit_slices ( $bufs: expr, $n: expr) {
1636- ' slices: {
1637- let bufs: & [ IoSlice < ' _ > ] = $bufs;
1638- let n: usize = $n;
1639- super let empty = & [ IoSlice :: new ( & [ ] ) ] ;
1640- if bufs. len ( ) > n || bufs. is_empty ( ) {
1641- crate :: hint:: cold_path ( ) ;
1642- for ( i, buf) in bufs. iter ( ) . enumerate ( ) {
1639+ pub ( crate ) macro limit_slices ( & mut $bufs: ident, $n: expr) {
1640+ // Rebind $bufs, so the lifetime does not need to live as long as the
1641+ // function parameter, and shadow it so the macro caller gets the result.
1642+ let mut $bufs: & [ IoSlice < ' _ > ] = $bufs;
1643+ let n: usize = $n;
1644+
1645+ let empty = & [ IoSlice :: new ( & [ ] ) ] ;
1646+
1647+ if $bufs. len ( ) > n || $bufs. is_empty ( ) {
1648+ crate :: hint:: cold_path ( ) ;
1649+ ' fixup: {
1650+ // Find the first non-empty buffer and take up to `n` buffers after it.
1651+ for ( i, buf) in $bufs. iter ( ) . enumerate ( ) {
16431652 if !buf. is_empty ( ) {
1644- // Take all buffers after the first non-empty buffer,
1645- // clamped to `n`.
1646- let len = cmp:: min ( bufs. len ( ) - i, n) ;
1647- break ' slices & bufs[ i..i + len] ;
1653+ let len = cmp:: min ( $bufs. len ( ) - i, n) ;
1654+ $bufs = & $bufs[ i..i + len] ;
1655+ break ' fixup;
16481656 }
16491657 }
1650- // POSIX requires at least one buffer for writev.
1651- // https://pubs.opengroup.org/onlinepubs/9799919799/functions/writev.html
1652- break ' slices empty;
1658+ // If no non-empty buffer is found, use a single empty buffer.
1659+ $bufs = empty;
16531660 }
1654- bufs
16551661 }
16561662}
16571663
@@ -1660,27 +1666,33 @@ pub(crate) macro limit_slices($bufs:expr, $n:expr) {
16601666///
16611667/// When the slice contains over `n` buffers, ensure that at least one non-empty
16621668/// buffer is in the truncated slice, if there is one.
1669+ ///
1670+ /// For example, [POSIX readv] requires that `bufs.len()` is in `1..=IOV_MAX`.
1671+ ///
1672+ /// [POSIX readv]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/readv.html
16631673#[ allow( unused_macros) ] // Not used on all platforms
1664- pub ( crate ) macro limit_slices_mut ( $bufs: expr, $n: expr) {
1665- ' slices: {
1666- let bufs: & mut [ IoSliceMut < ' _ > ] = $bufs;
1667- let n: usize = $n;
1668- super let empty = & mut [ IoSliceMut :: new ( & mut [ ] ) ] ;
1669- if bufs. len ( ) > n || bufs. is_empty ( ) {
1670- crate :: hint:: cold_path ( ) ;
1671- for ( i, buf) in bufs. iter ( ) . enumerate ( ) {
1674+ pub ( crate ) macro limit_slices_mut ( & mut $bufs: ident, $n: expr) {
1675+ // Rebind $bufs, so the lifetime does not need to live as long as the
1676+ // function parameter, and shadow it so the macro caller gets the result.
1677+ let mut $bufs: & mut [ IoSliceMut < ' _ > ] = $bufs;
1678+ let n: usize = $n;
1679+
1680+ let empty = & mut [ IoSliceMut :: new ( & mut [ ] ) ] ;
1681+
1682+ if $bufs. len ( ) > n || $bufs. is_empty ( ) {
1683+ crate :: hint:: cold_path ( ) ;
1684+ ' fixup: {
1685+ // Find the first non-empty buffer and take up to `n` buffers after it.
1686+ for ( i, buf) in $bufs. iter ( ) . enumerate ( ) {
16721687 if !buf. is_empty ( ) {
1673- // Take all buffers after the first non-empty buffer,
1674- // clamped to `n`.
1675- let len = cmp:: min ( bufs. len ( ) - i, n) ;
1676- break ' slices & mut bufs[ i..i + len] ;
1688+ let len = cmp:: min ( $bufs. len ( ) - i, n) ;
1689+ $bufs = & mut $bufs[ i..i + len] ;
1690+ break ' fixup;
16771691 }
16781692 }
1679- // POSIX requires at least one buffer for readv.
1680- // https://pubs.opengroup.org/onlinepubs/9799919799/functions/readv.html
1681- break ' slices empty;
1693+ // If no non-empty buffer is found, use a single empty buffer.
1694+ $bufs = empty;
16821695 }
1683- bufs
16841696 }
16851697}
16861698
0 commit comments