From e42295c4c51a35132595a7579de8467a38bc8171 Mon Sep 17 00:00:00 2001 From: alexmoon Date: Mon, 4 Apr 2022 21:24:10 -0400 Subject: [PATCH] Remove Unpin bound from SelectAll --- embassy/src/util/select_all.rs | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/embassy/src/util/select_all.rs b/embassy/src/util/select_all.rs index 1b9bddd6..aef22d89 100644 --- a/embassy/src/util/select_all.rs +++ b/embassy/src/util/select_all.rs @@ -1,11 +1,7 @@ -#![allow(dead_code)] - use core::future::Future; use core::pin::Pin; use core::task::{Context, Poll}; -use futures::future::FutureExt; - /// Future for the [`select_all`] function. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] @@ -24,9 +20,9 @@ impl Unpin for SelectAll {} /// # Panics /// /// This function will panic if the array specified contains no items. -pub fn select_all(arr: [Fut; N]) -> Option> { +pub fn select_all(arr: [Fut; N]) -> SelectAll { assert!(N > 0); - Some(SelectAll { inner: arr }) + SelectAll { inner: arr } } impl SelectAll { @@ -36,18 +32,24 @@ impl SelectAll { } } -impl Future for SelectAll { +impl Future for SelectAll { type Output = (Fut::Output, usize); - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let item = self - .inner - .iter_mut() - .enumerate() - .find_map(|(i, f)| match f.poll_unpin(cx) { - Poll::Pending => None, - Poll::Ready(e) => Some((i, e)), - }); + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + // Safety: Since `self` is pinned, `inner` cannot move. Since `inner` cannot move, + // its elements also cannot move. Therefore it is safe to access `inner` and pin + // references to the contained futures. + let item = unsafe { + self.get_unchecked_mut() + .inner + .iter_mut() + .enumerate() + .find_map(|(i, f)| match Pin::new_unchecked(f).poll(cx) { + Poll::Pending => None, + Poll::Ready(e) => Some((i, e)), + }) + }; + match item { Some((idx, res)) => Poll::Ready((res, idx)), None => Poll::Pending,