diff --git a/src/libcore/rt.rs b/src/libcore/rt.rs index f4e3463f0b7..120103bd656 100644 --- a/src/libcore/rt.rs +++ b/src/libcore/rt.rs @@ -26,9 +26,6 @@ use gc::{cleanup_stack_for_failure, gc, Word}; pub type rust_task = c_void; extern mod rustrt { - #[rust_stack] - fn rust_upcall_fail(expr: *c_char, file: *c_char, line: size_t); - #[rust_stack] fn rust_upcall_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char; @@ -47,11 +44,7 @@ extern mod rustrt { // gather_rust_rtcalls. #[rt(fail_)] pub fn rt_fail_(expr: *c_char, file: *c_char, line: size_t) -> ! { - unsafe { - cleanup_stack_for_failure(); - rustrt::rust_upcall_fail(expr, file, line); - cast::transmute(()) - } + sys::begin_unwind_(expr, file, line); } #[rt(fail_bounds_check)] diff --git a/src/libcore/sys.rs b/src/libcore/sys.rs index 7d5d644719f..62ced601951 100644 --- a/src/libcore/sys.rs +++ b/src/libcore/sys.rs @@ -15,7 +15,7 @@ #[forbid(deprecated_pattern)]; use cmp::{Eq, Ord}; -use libc::c_void; +use libc::{c_void, c_char, size_t}; pub type FreeGlue = fn(*TypeDesc, *c_void); @@ -43,6 +43,11 @@ extern mod rusti { fn min_align_of() -> uint; } +extern mod rustrt { + #[rust_stack] + fn rust_upcall_fail(expr: *c_char, file: *c_char, line: size_t); +} + /// Compares contents of two pointers using the default method. /// Equivalent to `*x1 == *x2`. Useful for hashtables. pub pure fn shape_eq(x1: &T, x2: &T) -> bool { @@ -108,6 +113,28 @@ pub pure fn log_str(t: &T) -> ~str { } } +/** Initiate task failure */ +pub pure fn begin_unwind(msg: ~str, file: ~str, line: uint) -> ! { + do str::as_buf(msg) |msg_buf, _msg_len| { + do str::as_buf(file) |file_buf, _file_len| { + unsafe { + let msg_buf = cast::transmute(msg_buf); + let file_buf = cast::transmute(file_buf); + begin_unwind_(msg_buf, file_buf, line as libc::size_t) + } + } + } +} + +// XXX: Temorary until rt::rt_fail_ goes away +pub pure fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! { + unsafe { + gc::cleanup_stack_for_failure(); + rustrt::rust_upcall_fail(msg, file, line); + cast::transmute(()) + } +} + #[cfg(test)] pub mod tests { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 1890ec36bdd..e9d871752aa 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -378,21 +378,10 @@ fn core_macros() -> ~str { macro_rules! die( ($msg: expr) => ( - { - do core::str::as_buf($msg) |msg_buf, _msg_len| { - do core::str::as_buf(file!()) |file_buf, _file_len| { - unsafe { - let msg_buf = core::cast::transmute(msg_buf); - let file_buf = core::cast::transmute(file_buf); - let line = line!() as core::libc::size_t; - core::rt::rt_fail_(msg_buf, file_buf, line) - } - } - } - } + core::sys::begin_unwind($msg, file!(), line!()) ); () => ( - die!(\"explicit failure\") + die!(~\"explicit failure\") ) ) }"; diff --git a/src/test/compile-fail/die-not-unique.rs b/src/test/compile-fail/die-not-unique.rs new file mode 100644 index 00000000000..bbda5332c77 --- /dev/null +++ b/src/test/compile-fail/die-not-unique.rs @@ -0,0 +1,5 @@ +// error-pattern:mismatched types + +fn main() { + die!("test"); +} diff --git a/src/test/run-fail/die-macro-expr.rs b/src/test/run-fail/die-macro-expr.rs new file mode 100644 index 00000000000..3d293fc805d --- /dev/null +++ b/src/test/run-fail/die-macro-expr.rs @@ -0,0 +1,5 @@ +// error-pattern:test + +fn main() { + let i: int = die!(~"test"); +} \ No newline at end of file diff --git a/src/test/run-fail/die-macro-pure.rs b/src/test/run-fail/die-macro-pure.rs new file mode 100644 index 00000000000..67eb6e63230 --- /dev/null +++ b/src/test/run-fail/die-macro-pure.rs @@ -0,0 +1,9 @@ +// error-pattern:test + +pure fn f() { + die!(~"test"); +} + +fn main() { + f(); +} \ No newline at end of file diff --git a/src/test/run-fail/die-macro.rs b/src/test/run-fail/die-macro.rs new file mode 100644 index 00000000000..0885c17e121 --- /dev/null +++ b/src/test/run-fail/die-macro.rs @@ -0,0 +1,5 @@ +// error-pattern:test + +fn main() { + die!(~"test"); +} \ No newline at end of file diff --git a/src/test/run-pass/die-macro.rs b/src/test/run-pass/die-macro.rs new file mode 100644 index 00000000000..59d297473fe --- /dev/null +++ b/src/test/run-pass/die-macro.rs @@ -0,0 +1,11 @@ +// Just testing that die!() type checks in statement or expr + +fn f() { + die!(); + + let x: int = die!(); +} + +fn main() { + +}