Skip to content

Commit 944e43d

Browse files
taiki-eStjepan Glavina
authored and
Stjepan Glavina
committed
Remove Pin API related unsafe code by using pin-project-lite cra… (#381)
1 parent ec23632 commit 944e43d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+894
-825
lines changed

Diff for: Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pin-utils = "0.1.0-alpha.4"
4343
slab = "0.4.2"
4444
kv-log-macro = "1.0.4"
4545
broadcaster = { version = "0.2.6", optional = true, default-features = false, features = ["default-channels"] }
46+
pin-project-lite = "0.1"
4647

4748
[dev-dependencies]
4849
femme = "1.2.0"

Diff for: src/future/timeout.rs

+13-12
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::pin::Pin;
44
use std::time::Duration;
55

66
use futures_timer::Delay;
7+
use pin_project_lite::pin_project;
78

89
use crate::future::Future;
910
use crate::task::{Context, Poll};
@@ -39,24 +40,24 @@ where
3940
f.await
4041
}
4142

42-
/// A future that times out after a duration of time.
43-
struct TimeoutFuture<F> {
44-
future: F,
45-
delay: Delay,
46-
}
47-
48-
impl<F> TimeoutFuture<F> {
49-
pin_utils::unsafe_pinned!(future: F);
50-
pin_utils::unsafe_pinned!(delay: Delay);
43+
pin_project! {
44+
/// A future that times out after a duration of time.
45+
struct TimeoutFuture<F> {
46+
#[pin]
47+
future: F,
48+
#[pin]
49+
delay: Delay,
50+
}
5151
}
5252

5353
impl<F: Future> Future for TimeoutFuture<F> {
5454
type Output = Result<F::Output, TimeoutError>;
5555

56-
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
57-
match self.as_mut().future().poll(cx) {
56+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
57+
let this = self.project();
58+
match this.future.poll(cx) {
5859
Poll::Ready(v) => Poll::Ready(Ok(v)),
59-
Poll::Pending => match self.delay().poll(cx) {
60+
Poll::Pending => match this.delay.poll(cx) {
6061
Poll::Ready(_) => Poll::Ready(Err(TimeoutError { _private: () })),
6162
Poll::Pending => Poll::Pending,
6263
},

Diff for: src/io/buf_read/lines.rs

+34-29
Original file line numberDiff line numberDiff line change
@@ -2,50 +2,55 @@ use std::mem;
22
use std::pin::Pin;
33
use std::str;
44

5+
use pin_project_lite::pin_project;
6+
57
use super::read_until_internal;
68
use crate::io::{self, BufRead};
79
use crate::stream::Stream;
810
use crate::task::{Context, Poll};
911

10-
/// A stream of lines in a byte stream.
11-
///
12-
/// This stream is created by the [`lines`] method on types that implement [`BufRead`].
13-
///
14-
/// This type is an async version of [`std::io::Lines`].
15-
///
16-
/// [`lines`]: trait.BufRead.html#method.lines
17-
/// [`BufRead`]: trait.BufRead.html
18-
/// [`std::io::Lines`]: https://doc.rust-lang.org/std/io/struct.Lines.html
19-
#[derive(Debug)]
20-
pub struct Lines<R> {
21-
pub(crate) reader: R,
22-
pub(crate) buf: String,
23-
pub(crate) bytes: Vec<u8>,
24-
pub(crate) read: usize,
12+
pin_project! {
13+
/// A stream of lines in a byte stream.
14+
///
15+
/// This stream is created by the [`lines`] method on types that implement [`BufRead`].
16+
///
17+
/// This type is an async version of [`std::io::Lines`].
18+
///
19+
/// [`lines`]: trait.BufRead.html#method.lines
20+
/// [`BufRead`]: trait.BufRead.html
21+
/// [`std::io::Lines`]: https://doc.rust-lang.org/std/io/struct.Lines.html
22+
#[derive(Debug)]
23+
pub struct Lines<R> {
24+
#[pin]
25+
pub(crate) reader: R,
26+
pub(crate) buf: String,
27+
pub(crate) bytes: Vec<u8>,
28+
pub(crate) read: usize,
29+
}
2530
}
2631

2732
impl<R: BufRead> Stream for Lines<R> {
2833
type Item = io::Result<String>;
2934

3035
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
31-
let Self {
32-
reader,
33-
buf,
34-
bytes,
35-
read,
36-
} = unsafe { self.get_unchecked_mut() };
37-
let reader = unsafe { Pin::new_unchecked(reader) };
38-
let n = futures_core::ready!(read_line_internal(reader, cx, buf, bytes, read))?;
39-
if n == 0 && buf.is_empty() {
36+
let this = self.project();
37+
let n = futures_core::ready!(read_line_internal(
38+
this.reader,
39+
cx,
40+
this.buf,
41+
this.bytes,
42+
this.read
43+
))?;
44+
if n == 0 && this.buf.is_empty() {
4045
return Poll::Ready(None);
4146
}
42-
if buf.ends_with('\n') {
43-
buf.pop();
44-
if buf.ends_with('\r') {
45-
buf.pop();
47+
if this.buf.ends_with('\n') {
48+
this.buf.pop();
49+
if this.buf.ends_with('\r') {
50+
this.buf.pop();
4651
}
4752
}
48-
Poll::Ready(Some(Ok(mem::replace(buf, String::new()))))
53+
Poll::Ready(Some(Ok(mem::replace(this.buf, String::new()))))
4954
}
5055
}
5156

Diff for: src/io/buf_read/split.rs

+32-27
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,51 @@
11
use std::mem;
22
use std::pin::Pin;
33

4+
use pin_project_lite::pin_project;
5+
46
use super::read_until_internal;
57
use crate::io::{self, BufRead};
68
use crate::stream::Stream;
79
use crate::task::{Context, Poll};
810

9-
/// A stream over the contents of an instance of [`BufRead`] split on a particular byte.
10-
///
11-
/// This stream is created by the [`split`] method on types that implement [`BufRead`].
12-
///
13-
/// This type is an async version of [`std::io::Split`].
14-
///
15-
/// [`split`]: trait.BufRead.html#method.lines
16-
/// [`BufRead`]: trait.BufRead.html
17-
/// [`std::io::Split`]: https://doc.rust-lang.org/std/io/struct.Split.html
18-
#[derive(Debug)]
19-
pub struct Split<R> {
20-
pub(crate) reader: R,
21-
pub(crate) buf: Vec<u8>,
22-
pub(crate) read: usize,
23-
pub(crate) delim: u8,
11+
pin_project! {
12+
/// A stream over the contents of an instance of [`BufRead`] split on a particular byte.
13+
///
14+
/// This stream is created by the [`split`] method on types that implement [`BufRead`].
15+
///
16+
/// This type is an async version of [`std::io::Split`].
17+
///
18+
/// [`split`]: trait.BufRead.html#method.lines
19+
/// [`BufRead`]: trait.BufRead.html
20+
/// [`std::io::Split`]: https://doc.rust-lang.org/std/io/struct.Split.html
21+
#[derive(Debug)]
22+
pub struct Split<R> {
23+
#[pin]
24+
pub(crate) reader: R,
25+
pub(crate) buf: Vec<u8>,
26+
pub(crate) read: usize,
27+
pub(crate) delim: u8,
28+
}
2429
}
2530

2631
impl<R: BufRead> Stream for Split<R> {
2732
type Item = io::Result<Vec<u8>>;
2833

2934
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
30-
let Self {
31-
reader,
32-
buf,
33-
read,
34-
delim,
35-
} = unsafe { self.get_unchecked_mut() };
36-
let reader = unsafe { Pin::new_unchecked(reader) };
37-
let n = futures_core::ready!(read_until_internal(reader, cx, *delim, buf, read))?;
38-
if n == 0 && buf.is_empty() {
35+
let this = self.project();
36+
let n = futures_core::ready!(read_until_internal(
37+
this.reader,
38+
cx,
39+
*this.delim,
40+
this.buf,
41+
this.read
42+
))?;
43+
if n == 0 && this.buf.is_empty() {
3944
return Poll::Ready(None);
4045
}
41-
if buf[buf.len() - 1] == *delim {
42-
buf.pop();
46+
if this.buf[this.buf.len() - 1] == *this.delim {
47+
this.buf.pop();
4348
}
44-
Poll::Ready(Some(Ok(mem::replace(buf, vec![]))))
49+
Poll::Ready(Some(Ok(mem::replace(this.buf, vec![]))))
4550
}
4651
}

0 commit comments

Comments
 (0)