mozilla/rust — pull request #9967 by Kimundi (2013-10-19 23:38:17+00:00)
Title: Allow fail messages to be caught, introduce Any trait

# Summary

This PR allows the cause of a failure to be received in a task's future result and as the `Err` case of `task::try`, and also implements dynamic typing in form of an `Any` trait.

# Task failure

- `fail!` and related macros now accept 4 possible types: `~str`, `&'static str`, `std::send_str::SendStr` and `~std::any::Any`
- `std::task::TaskResult`'s `Failure` variant now contains a value of type `FailCause`
- A `FailCause` can be one of three variants:
- `FailCauseStr(SendStr)`, this maps to failing with a value of type `~str`, `&'static str` or `SendStr`.
- `FailCauseAny(~Any)`, this maps to failing with an `~Any` value.
- `FailCauseLinked`, if the task got killed by linked task failure
- The `TaskResult` is exposed as before by `TaskBuilder`'s `future_result()` and by `task::try`

# Any

- In order to allow failing with arbitrary data, the `Any` trait got implemented.
- It is being used in form of a trait object, usually `~Any` or `&Any`.
- `&Any`, `~Any`, `@Any` and `&mut Any` have a few extension methods implemented on them:
- `is(&self) -> bool` returns true if the `Any` object contains type `T`
- `as_ref(&self) -> Option<&T>` returns a reference to the contained type, if it is `T`
- `as_mut(&mut self) -> Option<&mut T>` returns a mutable reference to the contained type, if it is `T`
- `move(self) -> Option<~T>` allows to get the `~T` out of a `~Any` again.
- `Any` currently uses type descriptors as a type id for comparisons, which is
- not reliable, as it is not guaranteed that every type has only one type descriptor.
- But safe, as no two types share the same type descriptor.
- The implementation also contains a few `transmute`-ed workarounds, especially for the implementations on `&mut Any`. Careful review is necessary, as I'm not sure if my assumptions where correct everywhere!

# Other changes

- `std::unstable::UnsafeArc::try_unwrap` no longer uses `Either`, bringing us one step closer to removing `Either`
- A few of the touched modules got their import lines sorted
- A few stylistic cleanups here and there