Skip to content
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

PinMut::get_mut_unchecked, Add Sized bound to poll_unpin #1049

Merged
merged 1 commit into from
Jun 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
12 changes: 6 additions & 6 deletions futures-util/src/future/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ impl<Fut1, Fut2, Data> Chain<Fut1, Fut2, Data>
let mut f = Some(f);

loop {
// safe to `get_mut` here because we don't move out
let fut2 = match unsafe { PinMut::get_mut(self.reborrow()) } {
// Safe to use `get_mut_unchecked` here because we don't move out
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 @@ -37,17 +37,17 @@ impl<Fut1, Fut2, Data> Chain<Fut1, Fut2, Data>
}
}
Chain::Second(fut2) => {
// safe to create a new `PinMut` because `fut2` will never move
// Safe to create a new `PinMut` because `fut2` will never move
// before it's dropped; once we're in `Chain::Second` we stay
// there forever.
return unsafe { PinMut::new_unchecked(fut2) }.poll(cx)
}
};

// safe because we're using the `&mut` to do an assignment, not for moving out
// 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);
// Note: It's safe to move the `fut2` here because we haven't yet polled it
*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
12 changes: 6 additions & 6 deletions futures-util/src/try_future/and_then.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ 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 {
// Safe to use `get_mut_unchecked` here because we don't move out
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 @@ -48,17 +48,17 @@ impl<A, B, F> Future for AndThen<A, B, F>
}
}
State::Second(fut2) => {
// safe to create a new `PinMut` because `fut2` will never move
// Safe to create a new `PinMut` because `fut2` will never move
// before it's dropped; once we're in `Chain::Second` we stay
// there forever.
return unsafe { PinMut::new_unchecked(fut2) }.try_poll(cx)
}
};

// safe because we're using the `&mut` to do an assignment, not for moving out
// 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);
// Note: it's safe to move the `fut2` here because we haven't yet polled it
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
14 changes: 7 additions & 7 deletions futures-util/src/try_future/or_else.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ 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 use `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
// Safe to create a new `PinMut` because `fut1` will never move
// before it's dropped.
match unsafe { PinMut::new_unchecked(fut1) }.try_poll(cx) {
Poll::Pending => return Poll::Pending,
Expand All @@ -48,17 +48,17 @@ impl<A, B, F> Future for OrElse<A, B, F>
}
}
State::Second(ref mut fut2) => {
// safe to create a new `PinMut` because `fut2` will never move
// Safe to create a new `PinMut` because `fut2` will never move
// before it's dropped; once we're in `Chain::Second` we stay
// there forever.
return unsafe { PinMut::new_unchecked(fut2) }.try_poll(cx)
}
};

// safe because we're using the `&mut` to do an assignment, not for moving out
// 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);
// Note: It's safe to move the `fut2` here because we haven't yet polled it
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