Created
June 4, 2014 01:13
-
-
Save wycats/f026a7cdf9ccfe401072 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate debug; | |
use std::mem::transmute; | |
use std::raw::Closure; | |
use std::rt::task::Task; | |
use std::rt::local::Local; | |
use std::any::{Any, AnyRefExt}; | |
struct RawUnwinder { | |
unwinding: bool, | |
cause: Option<Box<Any:Send>> | |
} | |
#[deriving(Show)] | |
struct Inner { | |
text: String | |
} | |
#[deriving(Show)] | |
struct Args<'a> { | |
fail: bool, | |
first: String, | |
second: Vec<&'static str>, | |
reference: Option<&'a Inner> | |
} | |
fn main() { | |
let inner = Inner { text: "Heyo".to_str() }; | |
let args = box Args { fail: false, first: "hello".to_str(), second: vec!("world", "and", "stuff"), reference: Some(&inner) }; | |
let fail = box Args { fail: true, first: "hello".to_str(), second: vec!(), reference: None }; | |
let success: || = unsafe { | |
let synth = Closure { code: transmute(testing), env: transmute(args) }; | |
transmute(synth) | |
}; | |
let failure: || = unsafe { | |
let synth = Closure { code: transmute(testing), env: transmute(fail) }; | |
transmute(synth) | |
}; | |
let old: Box<Task> = Local::take(); | |
let handle: *mut Task = unsafe { *transmute::<&Box<Task>, &*mut Task>(&old) }; | |
Local::put(old); | |
success(); | |
unsafe { | |
let unwinder = &mut ((*handle).unwinder); | |
unwinder.try(success); | |
unwinder.try(failure); | |
let raw: &RawUnwinder = transmute(unwinder); | |
match raw.cause { | |
None => (), | |
Some(ref err) => println!("{}", cause_str(err)) | |
} | |
} | |
} | |
fn testing(args: &Args) { | |
if args.fail { fail!("YOLO BROLO"); } | |
println!("{}", args); | |
} | |
fn cause_str(reason: &Box<Any:Send>) -> String { | |
match reason.as_ref::<&'static str>() { | |
Some(s) => *s, | |
None => match reason.as_ref::<String>() { | |
Some(s) => s.as_slice(), | |
None => "Box<Any>", | |
} | |
}.to_str() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment