From 5b64af3f38b80d7717d26a46ed49aeedd52b5d15 Mon Sep 17 00:00:00 2001 From: EFanZh Date: Fri, 17 Feb 2023 17:26:45 -0800 Subject: [PATCH] Ensure unreachable branch is eliminated (#2708) --- futures-util/src/future/select.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/futures-util/src/future/select.rs b/futures-util/src/future/select.rs index 80b67e670d..7e33d195f7 100644 --- a/futures-util/src/future/select.rs +++ b/futures-util/src/future/select.rs @@ -99,14 +99,24 @@ where type Output = Either<(A::Output, B), (B::Output, A)>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + /// When compiled with `-C opt-level=z`, this function will help the compiler eliminate the `None` branch, where + /// `Option::unwrap` does not. + #[inline(always)] + fn unwrap_option(value: Option) -> T { + match value { + None => unreachable!(), + Some(value) => value, + } + } + let (a, b) = self.inner.as_mut().expect("cannot poll Select twice"); if let Poll::Ready(val) = a.poll_unpin(cx) { - return Poll::Ready(Either::Left((val, self.inner.take().unwrap().1))); + return Poll::Ready(Either::Left((val, unwrap_option(self.inner.take()).1))); } if let Poll::Ready(val) = b.poll_unpin(cx) { - return Poll::Ready(Either::Right((val, self.inner.take().unwrap().0))); + return Poll::Ready(Either::Right((val, unwrap_option(self.inner.take()).0))); } Poll::Pending