Skip to content

Commit c179201

Browse files
committed
FillBuf: Do not call poll_fill_buf twice
1 parent e6735f3 commit c179201

File tree

1 file changed

+7
-13
lines changed

1 file changed

+7
-13
lines changed

futures-util/src/io/fill_buf.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use futures_core::task::{Context, Poll};
33
use futures_io::AsyncBufRead;
44
use std::io;
55
use std::pin::Pin;
6+
use std::slice;
67

78
/// Future for the [`fill_buf`](super::AsyncBufReadExt::fill_buf) method.
89
#[derive(Debug)]
@@ -30,19 +31,12 @@ where
3031
let reader = this.reader.take().expect("Polled FillBuf after completion");
3132

3233
match Pin::new(&mut *reader).poll_fill_buf(cx) {
33-
// We don't need to poll a second time for EOF, and doing so is likely to return Poll::Pending
34-
Poll::Ready(Ok(&[])) => Poll::Ready(Ok(&[])),
35-
// With polonius it is possible to remove this inner match and just have the correct
36-
// lifetime of the reference inferred based on which branch is taken
37-
Poll::Ready(Ok(_)) => match Pin::new(reader).poll_fill_buf(cx) {
38-
Poll::Ready(Ok(slice)) => Poll::Ready(Ok(slice)),
39-
Poll::Ready(Err(err)) => {
40-
unreachable!("reader indicated readiness but then returned an error: {:?}", err)
41-
}
42-
Poll::Pending => {
43-
unreachable!("reader indicated readiness but then returned pending")
44-
}
45-
},
34+
Poll::Ready(Ok(slice)) => {
35+
// With polonius it is possible to remove this lifetime transmutation and just have
36+
// the correct lifetime of the reference inferred based on which branch is taken
37+
let slice: &'a [u8] = unsafe { slice::from_raw_parts(slice.as_ptr(), slice.len()) };
38+
Poll::Ready(Ok(slice))
39+
}
4640
Poll::Ready(Err(err)) => Poll::Ready(Err(err)),
4741
Poll::Pending => {
4842
this.reader = Some(reader);

0 commit comments

Comments
 (0)