Skip to content

Commit d48ec2c

Browse files
authored
Reduce unsafe usage (#77)
1 parent 81bfb05 commit d48ec2c

File tree

3 files changed

+30
-27
lines changed

3 files changed

+30
-27
lines changed

async-stream/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ repository = "https://github.com/tokio-rs/async-stream"
1414
[dependencies]
1515
async-stream-impl = { version = "=0.3.3", path = "../async-stream-impl" }
1616
futures-core = "0.3"
17+
pin-project-lite = "0.2"
1718

1819
[dev-dependencies]
1920
futures-util = "0.3"

async-stream/src/async_stream.rs

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
use crate::yielder::Receiver;
22

33
use futures_core::{FusedStream, Stream};
4+
use pin_project_lite::pin_project;
45
use std::future::Future;
56
use std::pin::Pin;
67
use std::task::{Context, Poll};
78

8-
#[doc(hidden)]
9-
#[derive(Debug)]
10-
pub struct AsyncStream<T, U> {
11-
rx: Receiver<T>,
12-
done: bool,
13-
generator: U,
9+
pin_project! {
10+
#[doc(hidden)]
11+
#[derive(Debug)]
12+
pub struct AsyncStream<T, U> {
13+
rx: Receiver<T>,
14+
done: bool,
15+
#[pin]
16+
generator: U,
17+
}
1418
}
1519

1620
impl<T, U> AsyncStream<T, U> {
@@ -40,30 +44,28 @@ where
4044
type Item = T;
4145

4246
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
43-
unsafe {
44-
let me = Pin::get_unchecked_mut(self);
47+
let me = self.project();
4548

46-
if me.done {
47-
return Poll::Ready(None);
48-
}
49+
if *me.done {
50+
return Poll::Ready(None);
51+
}
4952

50-
let mut dst = None;
51-
let res = {
52-
let _enter = me.rx.enter(&mut dst);
53-
Pin::new_unchecked(&mut me.generator).poll(cx)
54-
};
53+
let mut dst = None;
54+
let res = {
55+
let _enter = me.rx.enter(&mut dst);
56+
me.generator.poll(cx)
57+
};
5558

56-
me.done = res.is_ready();
59+
*me.done = res.is_ready();
5760

58-
if dst.is_some() {
59-
return Poll::Ready(dst.take());
60-
}
61+
if dst.is_some() {
62+
return Poll::Ready(dst.take());
63+
}
6164

62-
if me.done {
63-
Poll::Ready(None)
64-
} else {
65-
Poll::Pending
66-
}
65+
if *me.done {
66+
Poll::Ready(None)
67+
} else {
68+
Poll::Pending
6769
}
6870
}
6971

async-stream/src/yielder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ impl<T> Future for Send<T> {
5353
return Poll::Ready(());
5454
}
5555

56-
STORE.with(|cell| unsafe {
56+
STORE.with(|cell| {
5757
let ptr = cell.get() as *mut Option<T>;
58-
let option_ref = ptr.as_mut().expect("invalid usage");
58+
let option_ref = unsafe { ptr.as_mut() }.expect("invalid usage");
5959

6060
if option_ref.is_none() {
6161
*option_ref = self.value.take();

0 commit comments

Comments
 (0)