diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs index bc748324fcd2b..ccc67e3f8b01c 100644 --- a/src/libstd/sync/future.rs +++ b/src/libstd/sync/future.rs @@ -132,7 +132,8 @@ impl Future { let (tx, rx) = channel(); spawn(proc() { - tx.send(blk()); + // Don't fail if the other end has hung up + let _ = tx.send_opt(blk()); }); Future::from_receiver(rx) @@ -144,6 +145,7 @@ mod test { use prelude::*; use sync::Future; use task; + use comm::{channel, Sender}; #[test] fn test_from_value() { @@ -206,4 +208,28 @@ mod test { assert_eq!(actual, expected); }); } + + #[test] + fn test_dropped_future_doesnt_fail() { + struct Bomb(Sender); + + local_data_key!(LOCAL: Bomb) + + impl Drop for Bomb { + fn drop(&mut self) { + let Bomb(ref tx) = *self; + tx.send(task::failing()); + } + } + + // Spawn a future, but drop it immediately. When we receive the result + // later on, we should never view the task as having failed. + let (tx, rx) = channel(); + drop(Future::spawn(proc() { + LOCAL.replace(Some(Bomb(tx))); + })); + + // Make sure the future didn't fail the task. + assert!(!rx.recv()); + } }