about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstd/any.rs7
-rw-r--r--src/libstd/rt/kill.rs4
-rw-r--r--src/libstd/rt/task.rs77
-rw-r--r--src/libstd/task/mod.rs23
-rw-r--r--src/libstd/task/spawn.rs6
5 files changed, 41 insertions, 76 deletions
diff --git a/src/libstd/any.rs b/src/libstd/any.rs
index 84ccf574ba7..8cd8ca23b45 100644
--- a/src/libstd/any.rs
+++ b/src/libstd/any.rs
@@ -20,7 +20,6 @@ use util::Void;
 
 ///////////////////////////////////////////////////////////////////////////////
 // TypeId
-// FIXME: #9913 - Needs proper intrinsic support to work reliably cross crate
 ///////////////////////////////////////////////////////////////////////////////
 
 /// `TypeId` represents a globally unique identifier for a type
@@ -199,8 +198,10 @@ mod tests {
 
     #[test]
     fn type_id() {
-        let (a, b, c) = (TypeId::of::<uint>(), TypeId::of::<&str>(), TypeId::of::<Test>());
-        let (d, e, f) = (TypeId::of::<uint>(), TypeId::of::<&str>(), TypeId::of::<Test>());
+        let (a, b, c) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
+                         TypeId::of::<Test>());
+        let (d, e, f) = (TypeId::of::<uint>(), TypeId::of::<&'static str>(),
+                         TypeId::of::<Test>());
 
         assert!(a != b);
         assert!(a != c);
diff --git a/src/libstd/rt/kill.rs b/src/libstd/rt/kill.rs
index 949421db9fc..2709c118191 100644
--- a/src/libstd/rt/kill.rs
+++ b/src/libstd/rt/kill.rs
@@ -155,9 +155,9 @@ use cell::Cell;
 use option::{Option, Some, None};
 use prelude::*;
 use rt::task::Task;
-use rt::task::UnwindMessageLinked;
 use rt::task::{UnwindResult, Failure};
 use task::spawn::Taskgroup;
+use task::LinkedFailure;
 use to_bytes::IterBytes;
 use unstable::atomics::{AtomicUint, Relaxed};
 use unstable::sync::{UnsafeArc, UnsafeArcSelf, UnsafeArcT, LittleLock};
@@ -597,7 +597,7 @@ impl Death {
                 }
 
                 if !success {
-                    result = Cell::new(Failure(UnwindMessageLinked));
+                    result = Cell::new(Failure(~LinkedFailure as ~Any));
                 }
             }
             on_exit(result.take());
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index b56dd0809df..cf7c291d189 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -36,6 +36,7 @@ use rt::logging::StdErrLogger;
 use rt::sched::{Scheduler, SchedHandle};
 use rt::stack::{StackSegment, StackPool};
 use send_str::SendStr;
+use task::LinkedFailure;
 use task::spawn::Taskgroup;
 use unstable::finally::Finally;
 
@@ -95,8 +96,8 @@ pub enum UnwindResult {
     /// The task is ending successfully
     Success,
 
-    /// The Task is failing with reason `UnwindMessage`
-    Failure(UnwindMessage),
+    /// The Task is failing with reason `~Any`
+    Failure(~Any),
 }
 
 impl UnwindResult {
@@ -119,27 +120,9 @@ impl UnwindResult {
     }
 }
 
-/// Represents the cause of a task failure
-#[deriving(ToStr)]
-pub enum UnwindMessage {
-    // FIXME: #9913 - This variant is not neccessary once Any works properly
-    /// Failed with a static string message
-    UnwindMessageStrStatic(&'static str),
-
-    // FIXME: #9913 - This variant is not neccessary once Any works properly
-    /// Failed with a owned string message
-    UnwindMessageStrOwned(~str),
-
-    /// Failed with an `~Any`
-    UnwindMessageAny(~Any),
-
-    /// Failed because of linked failure
-    UnwindMessageLinked
-}
-
 pub struct Unwinder {
     unwinding: bool,
-    cause: Option<UnwindMessage>
+    cause: Option<~Any>
 }
 
 impl Unwinder {
@@ -532,7 +515,7 @@ impl Unwinder {
         }
     }
 
-    pub fn begin_unwind(&mut self, cause: UnwindMessage) -> ! {
+    pub fn begin_unwind(&mut self, cause: ~Any) -> ! {
         #[fixed_stack_segment]; #[inline(never)];
 
         self.unwinding = true;
@@ -648,46 +631,34 @@ pub fn begin_unwind_raw(msg: *c_char, file: *c_char, line: size_t) -> ! {
 
 /// This is the entry point of unwinding for fail!() and assert!().
 pub fn begin_unwind<M: Any + Send>(msg: M, file: &'static str, line: uint) -> ! {
-    // Wrap the fail message in a `Any` box for uniform representation.
-    let any = ~msg as ~Any;
-
-    // FIXME: #9913 - This can be changed to be internal to begin_unwind_internal
-    // once Any works properly.
-    // As a workaround, string types need to be special cased right now
-    // because `Any` does not support dynamically querying whether the
-    // type implements a trait yet, so without requiring that every `Any`
-    // also implements `ToStr` there is no way to get a failure message
-    // out of it again during unwinding.
-    let msg = if any.is::<&'static str>() {
-        UnwindMessageStrStatic(*any.move::<&'static str>().unwrap())
-    } else if any.is::<~str>() {
-        UnwindMessageStrOwned(*any.move::<~str>().unwrap())
-    } else {
-        UnwindMessageAny(any)
-    };
-
-    begin_unwind_internal(msg, file, line)
-}
-
-fn begin_unwind_internal(msg: UnwindMessage, file: &'static str, line: uint) -> ! {
+    use any::AnyRefExt;
     use rt::in_green_task_context;
-    use rt::task::Task;
     use rt::local::Local;
+    use rt::task::Task;
     use str::Str;
     use unstable::intrinsics;
 
     unsafe {
-        // Be careful not to allocate in this block, if we're failing we may
-        // have been failing due to a lack of memory in the first place...
-
         let task: *mut Task;
+        // Note that this should be the only allocation performed in this block.
+        // Currently this means that fail!() on OOM will invoke this code path,
+        // but then again we're not really ready for failing on OOM anyway. If
+        // we do start doing this, then we should propagate this allocation to
+        // be performed in the parent of this task instead of the task that's
+        // failing.
+        let msg = ~msg as ~Any;
 
         {
-            let msg_s = match msg {
-                UnwindMessageAny(_) => "~Any",
-                UnwindMessageLinked => "linked failure",
-                UnwindMessageStrOwned(ref s)  => s.as_slice(),
-                UnwindMessageStrStatic(ref s) => s.as_slice(),
+            //let msg: &Any = msg;
+            let msg_s = match msg.as_ref::<&'static str>() {
+                Some(s) => *s,
+                None => match msg.as_ref::<~str>() {
+                    Some(s) => s.as_slice(),
+                    None => match msg.as_ref::<LinkedFailure>() {
+                        Some(*) => "linked failure",
+                        None => "~Any",
+                    }
+                }
             };
 
             if !in_green_task_context() {
diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs
index cdb70f00dfe..e75f8f6237f 100644
--- a/src/libstd/task/mod.rs
+++ b/src/libstd/task/mod.rs
@@ -60,8 +60,6 @@ use comm::{stream, Chan, GenericChan, GenericPort, Port, Peekable};
 use result::{Result, Ok, Err};
 use rt::in_green_task_context;
 use rt::local::Local;
-use rt::task::{UnwindMessageAny, UnwindMessageLinked};
-use rt::task::{UnwindMessageStrStatic, UnwindMessageStrOwned};
 use rt::task::{UnwindResult, Success, Failure};
 use send_str::{SendStr, IntoSendStr};
 use unstable::finally::Finally;
@@ -90,30 +88,25 @@ pub type TaskResult = Result<(), ~Any>;
 
 pub struct LinkedFailure;
 
-#[inline]
-fn wrap_as_any(res: UnwindResult) -> TaskResult {
-    match res {
-        Success => Ok(()),
-        Failure(UnwindMessageAny(a)) => Err(a),
-        Failure(UnwindMessageLinked) => Err(~LinkedFailure as ~Any),
-        Failure(UnwindMessageStrOwned(s))  => Err(~s as ~Any),
-        Failure(UnwindMessageStrStatic(s)) => Err(~s as ~Any),
-    }
-}
-
 pub struct TaskResultPort {
     priv port: Port<UnwindResult>
 }
 
+fn to_task_result(res: UnwindResult) -> TaskResult {
+    match res {
+        Success => Ok(()), Failure(a) => Err(a),
+    }
+}
+
 impl GenericPort<TaskResult> for TaskResultPort {
     #[inline]
     fn recv(&self) -> TaskResult {
-        wrap_as_any(self.port.recv())
+        to_task_result(self.port.recv())
     }
 
     #[inline]
     fn try_recv(&self) -> Option<TaskResult> {
-        self.port.try_recv().map(wrap_as_any)
+        self.port.try_recv().map(to_task_result)
     }
 }
 
diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs
index 4a98e396bbc..a4a43a01edd 100644
--- a/src/libstd/task/spawn.rs
+++ b/src/libstd/task/spawn.rs
@@ -83,11 +83,11 @@ use local_data;
 use rt::local::Local;
 use rt::sched::{Scheduler, Shutdown, TaskFromFriend};
 use rt::task::{Task, Sched};
-use rt::task::{UnwindMessageLinked, UnwindMessageStrStatic};
 use rt::task::{UnwindResult, Success, Failure};
 use rt::thread::Thread;
 use rt::work_queue::WorkQueue;
 use rt::{in_green_task_context, new_event_loop, KillHandle};
+use task::LinkedFailure;
 use task::SingleThreaded;
 use task::TaskOpts;
 use task::unkillable;
@@ -324,7 +324,7 @@ impl Drop for Taskgroup {
         do RuntimeGlue::with_task_handle_and_failing |me, failing| {
             if failing {
                 for x in self.notifier.mut_iter() {
-                    x.task_result = Some(Failure(UnwindMessageLinked));
+                    x.task_result = Some(Failure(~LinkedFailure as ~Any));
                 }
                 // Take everybody down with us. After this point, every
                 // other task in the group will see 'tg' as none, which
@@ -379,7 +379,7 @@ impl AutoNotify {
             notify_chan: chan,
 
             // Un-set above when taskgroup successfully made.
-            task_result: Some(Failure(UnwindMessageStrStatic("AutoNotify::new()")))
+            task_result: Some(Failure(~("AutoNotify::new()") as ~Any))
         }
     }
 }