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
99
99
type Output = Either < ( A :: Output , B ) , ( B :: Output , A ) > ;
100
100
101
101
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
+
102
115
let ( a, b) = self . inner . as_mut ( ) . expect ( "cannot poll Select twice" ) ;
103
116
104
117
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 ) ) ) ;
106
121
}
107
122
108
123
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 ) ) ) ;
110
127
}
111
128
112
129
Poll :: Pending
You can’t perform that action at this time.
0 commit comments