New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tracking issue for io_slice_advance #62726
Comments
Looking for some feedback as to whether this would be accepted. |
…omasdezeeuw Add {IoSlice, IoSliceMut}::advance API inspired by the [`Buf::advance`](https://docs.rs/bytes/0.4.12/bytes/trait.Buf.html#tymethod.advance) method found in the [bytes](https://docs.rs/bytes) crate. Closes rust-lang#62726.
Add {IoSlice, IoSliceMut}::advance API inspired by the [`Buf::advance`](https://docs.rs/bytes/0.4.12/bytes/trait.Buf.html#tymethod.advance) method found in the [bytes](https://docs.rs/bytes) crate. Closes #62726.
Can someone reopen this as the tracking issue for |
I was trying to impl Buf for IoSlice<'_> {
fn advance(&mut self, cnt: usize) {
*self = IoSlice::new(&self[cnt..]); // conflicting lifetime requirements
}
} To allow such a thing externally, we could add a method to impl<'a> IoSlice<'a> {
pub fn inner_ref(&self) -> &'a [u8] {
// ...
}
} |
@seanmonstar can get around the lifetime issues by replacing self with an empty slice and then replacing it again with the advanced slice? Something like can be found here: https://github.com/rust-lang/rust/pull/62987/files#diff-668f8f358d4a93474b396dcb3727399eR975. |
@Thomasdezeeuw I don't think so. It's not possible to get the inner slice with the same lifetime due to let tmp = std::mem::replace(self, IoSlice::new(&[]));
let tail = &tmp[cnt..]; // <- lifetime isn't same as `IoSlice<'a>`
*self = IoSlice::new(tail); |
@seanmonstar it's not an amazing API to build that on top of, but it is possible (playground): let mut slices = [std::mem::replace(self, IoSlice::new(&[]))];
let slices = IoSlice::advance(&mut slices[..], cnt);
match slices {
[slice] => {
*self = std::mem::replace(slice, IoSlice::new(&[]));
}
[] => {
*self = IoSlice::new(&[]);
}
_ => unreachable!(),
} |
Oh right, that is using the unstable function. I was referring to be able to implement this now. |
Ah, I just assumed since that's what the tracking issue is about. It seems like having |
I've been trying to write a |
Are there any news on landing this? I'm trying to do vectored IO too, and it would be very nice if it were possible to just use this function — I think this is the only unstable feature I currently depend on, and it would be very nice to be able to compile on stable without having to add unsafe code.
|
Are there any concerns with the current panic behavior? If not, can this be FCPed? |
Really looking forward for this being stabilized. This is quite useful in network programming. |
I do have one quick question prior to it stabilizing: do you want to require people to do fn write_all_vectored(&mut self, mut bufs: &mut [IoSlice<'_>]) -> Result<()> {
// Advance initially with `n = 0` to guarantee that bufs is empty if it
// contains no data, to avoid calling write_vectored if there is no data
// to be written.
let mut n = 0;
while IoSlice::advance_slices(&mut bufs, n) {
match self.write_vectored(bufs) {
Ok(0) => {
return Err(error::const_io_error!(
ErrorKind::WriteZero,
"failed to write whole buffer",
));
}
Ok(bytes) => n = bytes,
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
Ok(())
} The code itself already necessarily checks for this for the outer buffer, and it's pretty trivial for the inner buffer. |
How can progress be made on this issue? It is unclear to me what concerns are blocking this. |
@kalcutter it hasn't seen any changes for a year and half (?), so I think someone just needs to create a stabilisation pr. |
I think a FCP is needed first. |
Isn't that usually done in the stabilization pr? |
I'm not sure, but I have usually seen FCPs in tracking issues. |
+1 for starting FCP, this is a really useful feature |
This is a generally useful API for working with vectored I/O. @rfcbot fcp merge
I think making |
Team member @Amanieu has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
The |
FWIW, bytes provides advance on &[u8] via https://docs.rs/bytes/latest/bytes/trait.Buf.html. Is there a reason not to put advance directly on &[u8] here? I think that would be slightly incompatible to move later... |
Arguably it's inconsistent, since the other method takes a slice of However, I could see some benefit of moving both to methods via a pair of extension traits (say,
|
That's because the That said, I'm perfectly fine with changing |
rust/library/std/src/io/mod.rs Lines 1331 to 1354 in 55e5c9d
I think we may use |
I opened #116070 to handle that. |
…cked_add, r=Mark-Simulacrum Avoid overflow in `IoSlice::advance_slices` Noticed in rust-lang#62726 (comment).
…cked_add, r=Mark-Simulacrum Avoid overflow in `IoSlice::advance_slices` Noticed in rust-lang#62726 (comment).
…cked_add, r=Mark-Simulacrum Avoid overflow in `IoSlice::advance_slices` Noticed in rust-lang#62726 (comment).
… r=Mark-Simulacrum Avoid overflow in `IoSlice::advance_slices` Noticed in rust-lang/rust#62726 (comment).
Although it is also still unstable, a related set of functions on impl<T> MaybeUninit<T> {
pub fn slice_as_bytes(this: &[MaybeUninit<T>]) -> &[MaybeUninit<u8>];
} Applying the same here would read kind of odd though because of the repetition of impl<T> IoSlice<T> {
pub fn slice_advance(this &mut &mut [IoSlice<'a>], n: usize);
}
// in some impl
IoSlice::slice_advance(&mut bufs, n_read); Perhaps we could name them |
I fail to see the relation between the two functions. Can you elaborate why you think they should? |
impl IoSlice {
fn advance(&mut self, n: usize);
fn slice_advance(this &mut &mut [IoSlice<'a>], n: usize);
} Perhaps it should be a free-function instead and we offer only |
It is also worth noting that |
I still fail to see the relation, but those names seem fine with me as well. At this point I don't really care about the names to be honest.
See |
This is a tracking issue for
IoSlice::{advance, advance_slices}
andIoSliceMut::{advance, advance_slices}
.Feature gate: #![feature(io_slice_advance)].
Steps:
Current API additions:
Old issue:
Writing rust-lang/futures-rs#1741 I needed to resort to unsafe code to change the underlying slice in
IoSlice
(andIoSliceMut
). I'm missing a method that can change the underlying slice. @Nemo157 said that I should open an issue.Current idea would be something like
Buf::advance
from the bytes crate.The text was updated successfully, but these errors were encountered: