File tree Expand file tree Collapse file tree 1 file changed +19
-2
lines changed Expand file tree Collapse file tree 1 file changed +19
-2
lines changed Original file line number Diff line number Diff line change @@ -99,14 +99,31 @@ where
9999 type Output = Either < ( A :: Output , B ) , ( B :: Output , A ) > ;
100100
101101 fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
102+ /// # Safety
103+ ///
104+ /// `value` must be a `Some` value.
105+ #[ inline( always) ]
106+ unsafe fn take_unchecked < T > ( value : & mut Option < T > ) -> T {
107+ // `Option::unwrap_unchecked` is introduced in 1.58.0, so we can’t use it here.
108+ match value. take ( ) {
109+ // SAFETY: the safety contract must be upheld by the caller.
110+ None => core:: hint:: unreachable_unchecked ( ) ,
111+ Some ( value) => value,
112+ }
113+ }
114+
102115 let ( a, b) = self . inner . as_mut ( ) . expect ( "cannot poll Select twice" ) ;
103116
104117 if let Poll :: Ready ( val) = a. poll_unpin ( cx) {
105- return Poll :: Ready ( Either :: Left ( ( val, self . inner . take ( ) . unwrap ( ) . 1 ) ) ) ;
118+ // SAFETY: `a` refers to a future lives inside `self.inner`, which means `self.inner` must be a `Some`
119+ // value.
120+ return Poll :: Ready ( Either :: Left ( ( val, unsafe { take_unchecked ( & mut self . inner ) } . 1 ) ) ) ;
106121 }
107122
108123 if let Poll :: Ready ( val) = b. poll_unpin ( cx) {
109- return Poll :: Ready ( Either :: Right ( ( val, self . inner . take ( ) . unwrap ( ) . 0 ) ) ) ;
124+ // SAFETY: `b` refers to a future lives inside `self.inner`, which means `self.inner` must be a `Some`
125+ // value.
126+ return Poll :: Ready ( Either :: Right ( ( val, unsafe { take_unchecked ( & mut self . inner ) } . 0 ) ) ) ;
110127 }
111128
112129 Poll :: Pending
You can’t perform that action at this time.
0 commit comments