@@ -1321,12 +1321,13 @@ impl<T> Receiver<T> {
13211321 // Do an optimistic try_recv to avoid the performance impact of
13221322 // Instant::now() in the full-channel case.
13231323 match self . try_recv ( ) {
1324- Ok ( result)
1325- => Ok ( result) ,
1326- Err ( TryRecvError :: Disconnected )
1327- => Err ( RecvTimeoutError :: Disconnected ) ,
1328- Err ( TryRecvError :: Empty )
1329- => self . recv_deadline ( Instant :: now ( ) + timeout)
1324+ Ok ( result) => Ok ( result) ,
1325+ Err ( TryRecvError :: Disconnected ) => Err ( RecvTimeoutError :: Disconnected ) ,
1326+ Err ( TryRecvError :: Empty ) => match Instant :: now ( ) . checked_add ( timeout) {
1327+ Some ( deadline) => self . recv_deadline ( deadline) ,
1328+ // So far in the future that it's practically the same as waiting indefinitely.
1329+ None => self . recv ( ) . map_err ( RecvTimeoutError :: from) ,
1330+ } ,
13301331 }
13311332 }
13321333
@@ -2311,6 +2312,17 @@ mod tests {
23112312 assert_eq ! ( recv_count, stress) ;
23122313 }
23132314
2315+ #[ test]
2316+ fn very_long_recv_timeout_wont_panic ( ) {
2317+ let ( tx, rx) = channel :: < ( ) > ( ) ;
2318+ let join_handle = thread:: spawn ( move || {
2319+ rx. recv_timeout ( Duration :: from_secs ( u64:: max_value ( ) ) )
2320+ } ) ;
2321+ thread:: sleep ( Duration :: from_secs ( 1 ) ) ;
2322+ assert ! ( tx. send( ( ) ) . is_ok( ) ) ;
2323+ assert_eq ! ( join_handle. join( ) . unwrap( ) , Ok ( ( ) ) ) ;
2324+ }
2325+
23142326 #[ test]
23152327 fn recv_a_lot ( ) {
23162328 // Regression test that we don't run out of stack in scheduler context
0 commit comments