From b00449380f520deb65de26e654aeaba4561ee13f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 1 Nov 2013 11:20:01 -0700 Subject: [PATCH] Remove unnecessary unwind messages Now that the type_id intrinsic is working across crates, all of these unnecessary messages can be removed to have the failure type for a task truly be ~Any and only ~Any --- src/libstd/any.rs | 7 ++-- src/libstd/rt/kill.rs | 4 +-- src/libstd/rt/task.rs | 77 +++++++++++++--------------------------- src/libstd/task/mod.rs | 23 +++++------- src/libstd/task/spawn.rs | 6 ++-- 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::(), TypeId::of::<&str>(), TypeId::of::()); - let (d, e, f) = (TypeId::of::(), TypeId::of::<&str>(), TypeId::of::()); + let (a, b, c) = (TypeId::of::(), TypeId::of::<&'static str>(), + TypeId::of::()); + let (d, e, f) = (TypeId::of::(), TypeId::of::<&'static str>(), + TypeId::of::()); 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 + 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(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::() { + 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 } +fn to_task_result(res: UnwindResult) -> TaskResult { + match res { + Success => Ok(()), Failure(a) => Err(a), + } +} + impl GenericPort 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 { - 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)) } } }