Skip to content

Commit

Permalink
PinMut::get_mut_unchecked, Add Sized bound to poll_unpin
Browse files Browse the repository at this point in the history
  • Loading branch information
MajorBreakfast committed Jun 27, 2018
1 parent acffc9b commit 13a42df
Show file tree
Hide file tree
Showing 21 changed files with 47 additions and 45 deletions.
2 changes: 1 addition & 1 deletion futures-core/src/future/either.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl<A, B> Stream for Either<A, B>

fn poll_next(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Option<A::Item>> {
unsafe {
match PinMut::get_mut(self) {
match PinMut::get_mut_unchecked(self) {
Either::Left(a) => PinMut::new_unchecked(a).poll_next(cx),
Either::Right(b) => PinMut::new_unchecked(b).poll_next(cx),
}
Expand Down
4 changes: 2 additions & 2 deletions futures-core/src/future/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ pub use core::future::Future;
pub trait CoreFutureExt: Future {
/// A convenience for calling `Future::poll` on `Unpin` future types.
fn poll_unpin(&mut self, cx: &mut task::Context) -> Poll<Self::Output>
where Self: Unpin
where Self: Unpin + Sized
{
PinMut::new(self).poll(cx)
}
}

impl<T: ?Sized> CoreFutureExt for T where T: Future {}

/// A convenience for futures that return `Result` values that includes
/// a variety of adapters tailored to such futures.
pub trait TryFuture {
Expand Down
22 changes: 12 additions & 10 deletions futures-core/src/future/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,27 @@ use core::mem::PinMut;
/// Created by the `IntoFuture` implementation for `std::option::Option`.
#[derive(Debug, Clone)]
#[must_use = "futures do nothing unless polled"]
pub struct FutureOption<T> {
inner: Option<T>,
pub struct FutureOption<F> {
option: Option<F>,
}

impl<F> FutureOption<F> {
unsafe_pinned!(option -> Option<F>);
}

impl<F: Future> Future for FutureOption<F> {
type Output = Option<F::Output>;

fn poll(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
unsafe {
match &mut PinMut::get_mut(self).inner {
None => Poll::Ready(None),
Some(x) => PinMut::new_unchecked(x).poll(cx).map(Some),
}
fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
match self.option().as_pin_mut() {
Some(x) => x.poll(cx).map(Some),
None => Poll::Ready(None),
}
}
}

impl<T> From<Option<T>> for FutureOption<T> {
fn from(o: Option<T>) -> Self {
FutureOption { inner: o }
fn from(option: Option<T>) -> Self {
FutureOption { option }
}
}
6 changes: 3 additions & 3 deletions futures-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ macro_rules! if_std {
macro_rules! pinned_deref {
($e:expr) => (
::core::mem::PinMut::new_unchecked(
&mut **::core::mem::PinMut::get_mut($e.reborrow())
&mut **::core::mem::PinMut::get_mut_unchecked($e.reborrow())
)
)
}
Expand All @@ -36,7 +36,7 @@ macro_rules! pinned_deref {
macro_rules! pinned_field {
($e:expr, $f:tt) => (
::core::mem::PinMut::new_unchecked(
&mut ::core::mem::PinMut::get_mut($e.reborrow()).$f
&mut ::core::mem::PinMut::get_mut_unchecked($e.reborrow()).$f
)
)
}
Expand All @@ -57,7 +57,7 @@ macro_rules! unsafe_unpinned {
($f:tt -> $t:ty) => (
fn $f<'a>(self: &'a mut PinMut<Self>) -> &'a mut $t {
unsafe {
&mut ::core::mem::PinMut::get_mut(self.reborrow()).$f
&mut ::core::mem::PinMut::get_mut_unchecked(self.reborrow()).$f
}
}
)
Expand Down
4 changes: 2 additions & 2 deletions futures-core/src/stream/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub trait Stream {

/// A convenience for calling `Stream::poll_next` on `Unpin` stream types.
fn poll_next_unpin(&mut self, cx: &mut task::Context) -> Poll<Option<Self::Item>>
where Self: Unpin
where Self: Unpin + Sized
{
PinMut::new(self).poll_next(cx)
}
Expand Down Expand Up @@ -79,7 +79,7 @@ if_std! {
type Item = S::Item;

fn poll_next(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Option<Self::Item>> {
(**self).poll_next_unpin(cx)
PinMut::new(&mut **self).poll_next(cx)
}
}

Expand Down
12 changes: 6 additions & 6 deletions futures-sink/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ if_std! {

fn start_send(self: PinMut<Self>, item: Self::SinkItem) -> Result<(), Self::SinkError> {
// TODO: impl<T> Unpin for Vec<T> {}
unsafe { PinMut::get_mut(self) }.push(item);
unsafe { PinMut::get_mut_unchecked(self) }.push(item);
Ok(())
}

Expand All @@ -207,7 +207,7 @@ if_std! {

fn start_send(self: PinMut<Self>, item: Self::SinkItem) -> Result<(), Self::SinkError> {
// TODO: impl<T> Unpin for Vec<T> {}
unsafe { PinMut::get_mut(self) }.push_back(item);
unsafe { PinMut::get_mut_unchecked(self) }.push_back(item);
Ok(())
}

Expand Down Expand Up @@ -257,7 +257,7 @@ impl<A, B> Sink for Either<A, B>

fn poll_ready(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Result<(), Self::SinkError>> {
unsafe {
match PinMut::get_mut(self) {
match PinMut::get_mut_unchecked(self) {
Either::Left(x) => PinMut::new_unchecked(x).poll_ready(cx),
Either::Right(x) => PinMut::new_unchecked(x).poll_ready(cx),
}
Expand All @@ -266,7 +266,7 @@ impl<A, B> Sink for Either<A, B>

fn start_send(self: PinMut<Self>, item: Self::SinkItem) -> Result<(), Self::SinkError> {
unsafe {
match PinMut::get_mut(self) {
match PinMut::get_mut_unchecked(self) {
Either::Left(x) => PinMut::new_unchecked(x).start_send(item),
Either::Right(x) => PinMut::new_unchecked(x).start_send(item),
}
Expand All @@ -275,7 +275,7 @@ impl<A, B> Sink for Either<A, B>

fn poll_flush(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Result<(), Self::SinkError>> {
unsafe {
match PinMut::get_mut(self) {
match PinMut::get_mut_unchecked(self) {
Either::Left(x) => PinMut::new_unchecked(x).poll_flush(cx),
Either::Right(x) => PinMut::new_unchecked(x).poll_flush(cx),
}
Expand All @@ -284,7 +284,7 @@ impl<A, B> Sink for Either<A, B>

fn poll_close(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Result<(), Self::SinkError>> {
unsafe {
match PinMut::get_mut(self) {
match PinMut::get_mut_unchecked(self) {
Either::Left(x) => PinMut::new_unchecked(x).poll_close(cx),
Either::Right(x) => PinMut::new_unchecked(x).poll_close(cx),
}
Expand Down
4 changes: 2 additions & 2 deletions futures-util/src/future/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl<Fut1, Fut2, Data> Chain<Fut1, Fut2, Data>

loop {
// safe to `get_mut` here because we don't move out
let fut2 = match unsafe { PinMut::get_mut(self.reborrow()) } {
let fut2 = match unsafe { PinMut::get_mut_unchecked(self.reborrow()) } {
Chain::First(fut1, data) => {
// safe to create a new `PinMut` because `fut1` will never move
// before it's dropped.
Expand All @@ -47,7 +47,7 @@ impl<Fut1, Fut2, Data> Chain<Fut1, Fut2, Data>
// safe because we're using the `&mut` to do an assignment, not for moving out
unsafe {
// note: it's safe to move the `fut2` here because we haven't yet polled it
*PinMut::get_mut(self.reborrow()) = Chain::Second(fut2);
*PinMut::get_mut_unchecked(self.reborrow()) = Chain::Second(fut2);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions futures-util/src/future/flatten_stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl<F> Stream for FlattenStream<F>
fn poll_next(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Option<Self::Item>> {
loop {
// safety: data is never moved via the resulting &mut reference
let stream = match &mut unsafe { PinMut::get_mut(self.reborrow()) }.state {
let stream = match &mut unsafe { PinMut::get_mut_unchecked(self.reborrow()) }.state {
State::Future(f) => {
// safety: the future we're re-pinning here will never be moved;
// it will just be polled, then dropped in place
Expand All @@ -74,7 +74,7 @@ impl<F> Stream for FlattenStream<F>
unsafe {
// safety: we use the &mut only for an assignment, which causes
// only an in-place drop
PinMut::get_mut(self.reborrow()).state = State::Stream(stream);
PinMut::get_mut_unchecked(self.reborrow()).state = State::Stream(stream);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion futures-util/src/future/with_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl<F, E> Future for WithExecutor<F, E>
type Output = F::Output;

fn poll(self: PinMut<Self>, cx: &mut task::Context) -> Poll<F::Output> {
let this = unsafe { PinMut::get_mut(self) };
let this = unsafe { PinMut::get_mut_unchecked(self) };
let fut = unsafe { PinMut::new_unchecked(&mut this.future) };
let exec = &mut this.executor;
fut.poll(&mut cx.with_executor(exec))
Expand Down
2 changes: 1 addition & 1 deletion futures-util/src/io/split.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn lock_and_then<T, U, E, F>(lock: &BiLock<T>, cx: &mut task::Context, f: F) ->
match lock.poll_lock(cx) {
// Safety: the value behind the bilock used by `ReadHalf` and `WriteHalf` is never exposed
// as a `PinMut` anywhere other than here as a way to get to `&mut`.
Poll::Ready(mut l) => f(unsafe { PinMut::get_mut(l.as_pin_mut()) }, cx),
Poll::Ready(mut l) => f(unsafe { PinMut::get_mut_unchecked(l.as_pin_mut()) }, cx),
Poll::Pending => Poll::Pending,
}
}
Expand Down
2 changes: 1 addition & 1 deletion futures-util/src/sink/map_err.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl<S, F> SinkMapErr<S, F> {

/// Get a pinned reference to the inner sink.
pub fn get_pinned_mut<'a>(self: PinMut<'a, Self>) -> PinMut<'a, S> {
unsafe { PinMut::new_unchecked(&mut PinMut::get_mut(self).sink) }
unsafe { PinMut::new_unchecked(&mut PinMut::get_mut_unchecked(self).sink) }
}

/// Consumes this combinator, returning the underlying sink.
Expand Down
4 changes: 2 additions & 2 deletions futures-util/src/sink/with.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ enum State<Fut, T> {
impl<Fut, T> State<Fut, T> {
fn as_pin_mut<'a>(self: PinMut<'a, Self>) -> State<PinMut<'a, Fut>, PinMut<'a, T>> {
unsafe {
match PinMut::get_mut(self) {
match PinMut::get_mut_unchecked(self) {
State::Empty => State::Empty,
State::Process(fut) => State::Process(PinMut::new_unchecked(fut)),
State::Buffered(x) => State::Buffered(PinMut::new_unchecked(x)),
Expand Down Expand Up @@ -116,7 +116,7 @@ impl<S, U, Fut, F, E> With<S, U, Fut, F>
if let Some(buffered) = buffered {
PinMut::set(self.state(), State::Buffered(buffered));
}
if let State::Buffered(item) = unsafe { mem::replace(PinMut::get_mut(self.state()), State::Empty) } {
if let State::Buffered(item) = unsafe { mem::replace(PinMut::get_mut_unchecked(self.state()), State::Empty) } {
Poll::Ready(self.sink().start_send(item).map_err(Into::into))
} else {
unreachable!()
Expand Down
2 changes: 1 addition & 1 deletion futures-util/src/stream/fuse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ impl<S> Fuse<S> {
/// Note that care must be taken to avoid tampering with the state of the
/// stream which may otherwise confuse this combinator.
pub fn get_pin_mut<'a>(self: PinMut<'a, Self>) -> PinMut<'a, S> {
unsafe { PinMut::new_unchecked(&mut PinMut::get_mut(self).stream) }
unsafe { PinMut::new_unchecked(&mut PinMut::get_mut_unchecked(self).stream) }
}

/// Consumes this combinator, returning the underlying stream.
Expand Down
2 changes: 1 addition & 1 deletion futures-util/src/stream/futures_unordered/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl<'a, F: Unpin> Iterator for IterMut<'a, F> {
type Item = &'a mut F;

fn next(&mut self) -> Option<&'a mut F> {
self.0.next().map(|f| unsafe { PinMut::get_mut(f) })
self.0.next().map(|f| PinMut::get_mut(f))
}

fn size_hint(&self) -> (usize, Option<usize>) {
Expand Down
2 changes: 1 addition & 1 deletion futures-util/src/stream/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl<S1, S2> Select<S1, S2> {

fn project<'a>(self: PinMut<'a, Self>) -> (&'a mut bool, PinMut<'a, Fuse<S1>>, PinMut<'a, Fuse<S2>>) {
unsafe {
let Select { stream1, stream2, flag } = PinMut::get_mut(self);
let Select { stream1, stream2, flag } = PinMut::get_mut_unchecked(self);
(flag, PinMut::new_unchecked(stream1), PinMut::new_unchecked(stream2))
}
}
Expand Down
4 changes: 2 additions & 2 deletions futures-util/src/try_future/and_then.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl<A, B, F> Future for AndThen<A, B, F>
fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
loop {
// safe to `get_mut` here because we don't move out
let fut2 = match &mut unsafe { PinMut::get_mut(self.reborrow()) }.state {
let fut2 = match &mut unsafe { PinMut::get_mut_unchecked(self.reborrow()) }.state {
State::First(fut1, data) => {
// safe to create a new `PinMut` because `fut1` will never move
// before it's dropped.
Expand All @@ -58,7 +58,7 @@ impl<A, B, F> Future for AndThen<A, B, F>
// safe because we're using the `&mut` to do an assignment, not for moving out
unsafe {
// note: it's safe to move the `fut2` here because we haven't yet polled it
PinMut::get_mut(self.reborrow()).state = State::Second(fut2);
PinMut::get_mut_unchecked(self.reborrow()).state = State::Second(fut2);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion futures-util/src/try_future/flatten_sink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl<F, S> FlattenSink<F, S> {
-> State<PinMut<'a, F>, PinMut<'a, S>>
{
unsafe {
match &mut PinMut::get_mut(self).0 {
match &mut PinMut::get_mut_unchecked(self).0 {
Waiting(f) => Waiting(PinMut::new_unchecked(f)),
Ready(s) => Ready(PinMut::new_unchecked(s)),
Closed => Closed,
Expand Down
2 changes: 1 addition & 1 deletion futures-util/src/try_future/map_err.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl<U, A, F> Future for MapErr<A, F>
Poll::Pending => return Poll::Pending,
Poll::Ready(e) => {
let f = unsafe {
PinMut::get_mut(self).f.take().expect("cannot poll MapErr twice")
PinMut::get_mut_unchecked(self).f.take().expect("cannot poll MapErr twice")
};
Poll::Ready(e.map_err(f))
}
Expand Down
2 changes: 1 addition & 1 deletion futures-util/src/try_future/map_ok.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl<U, A, F> Future for MapOk<A, F>
Poll::Pending => return Poll::Pending,
Poll::Ready(e) => {
let f = unsafe {
PinMut::get_mut(self).f.take().expect("cannot poll MapOk twice")
PinMut::get_mut_unchecked(self).f.take().expect("cannot poll MapOk twice")
};
Poll::Ready(e.map(f))
}
Expand Down
6 changes: 3 additions & 3 deletions futures-util/src/try_future/or_else.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ impl<A, B, F> Future for OrElse<A, B, F>

fn poll(mut self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> {
loop {
// safe to `get_mut` here because we don't move out
let fut2 = match unsafe { PinMut::get_mut(self.reborrow()) }.state {
// safe to `get_mut_unchecked` here because we don't move out
let fut2 = match unsafe { PinMut::get_mut_unchecked(self.reborrow()) }.state {
State::First(ref mut fut1, ref mut data) => {
// safe to create a new `PinMut` because `fut1` will never move
// before it's dropped.
Expand All @@ -58,7 +58,7 @@ impl<A, B, F> Future for OrElse<A, B, F>
// safe because we're using the `&mut` to do an assignment, not for moving out
unsafe {
// note: it's safe to move the `fut2` here because we haven't yet polled it
PinMut::get_mut(self.reborrow()).state = State::Second(fut2);
PinMut::get_mut_unchecked(self.reborrow()).state = State::Second(fut2);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion futures-util/src/try_future/recover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl<A, F> Future for Recover<A, F>
unsafe { pinned_field!(self.reborrow(), inner) }.try_poll(cx)
.map(|res| res.unwrap_or_else(|e| {
let f = unsafe {
PinMut::get_mut(self).f.take()
PinMut::get_mut_unchecked(self).f.take()
.expect("Polled future::Recover after completion")
};
f(e)
Expand Down

0 comments on commit 13a42df

Please sign in to comment.