about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/char.rs4
-rw-r--r--src/libcore/failure.rs54
-rw-r--r--src/libcore/lib.rs8
-rw-r--r--src/libcore/macros.rs38
-rw-r--r--src/libcore/num/int_macros.rs54
-rw-r--r--src/libcore/num/uint_macros.rs30
-rw-r--r--src/libstd/rt/mod.rs2
-rw-r--r--src/libstd/rt/unwind.rs42
8 files changed, 155 insertions, 77 deletions
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index 9c00b6babc1..298a3b38ee5 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -214,7 +214,7 @@ pub fn is_digit_radix(c: char, radix: uint) -> bool {
 #[inline]
 pub fn to_digit(c: char, radix: uint) -> Option<uint> {
     if radix > 36 {
-        fail!("to_digit: radix {} is too high (maximum 36)", radix);
+        fail!("to_digit: radix is too high (maximum 36)");
     }
     let val = match c {
       '0' .. '9' => c as uint - ('0' as uint),
@@ -273,7 +273,7 @@ pub fn to_lowercase(c: char) -> char {
 #[inline]
 pub fn from_digit(num: uint, radix: uint) -> Option<char> {
     if radix > 36 {
-        fail!("from_digit: radix {} is to high (maximum 36)", num);
+        fail!("from_digit: radix is to high (maximum 36)");
     }
     if num < radix {
         unsafe {
diff --git a/src/libcore/failure.rs b/src/libcore/failure.rs
new file mode 100644
index 00000000000..efa24fa96f8
--- /dev/null
+++ b/src/libcore/failure.rs
@@ -0,0 +1,54 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Failure support for libcore
+
+#![allow(dead_code)]
+
+use str::raw::c_str_to_static_slice;
+
+// FIXME: Once std::fmt is in libcore, all of these functions should delegate
+//        to a common failure function with this signature:
+//
+//          extern {
+//              fn rust_unwind(f: &fmt::Arguments, file: &str, line: uint) -> !;
+//          }
+//
+//        Each of these functions can create a temporary fmt::Arguments
+//        structure to pass to this function.
+
+#[cold] #[inline(never)] // this is the slow path, always
+#[lang="fail_"]
+#[cfg(not(test))]
+fn fail_(expr: *u8, file: *u8, line: uint) -> ! {
+    unsafe {
+        let expr = c_str_to_static_slice(expr as *i8);
+        let file = c_str_to_static_slice(file as *i8);
+        begin_unwind(expr, file, line)
+    }
+}
+
+#[cold]
+#[lang="fail_bounds_check"]
+#[cfg(not(test))]
+fn fail_bounds_check(file: *u8, line: uint, index: uint, len: uint) -> ! {
+    #[allow(ctypes)]
+    extern { fn rust_fail_bounds_check(file: *u8, line: uint,
+                                       index: uint, len: uint,) -> !; }
+    unsafe { rust_fail_bounds_check(file, line, index, len) }
+}
+
+#[cold]
+pub fn begin_unwind(msg: &str, file: &'static str, line: uint) -> ! {
+    #[allow(ctypes)]
+    extern { fn rust_begin_unwind(msg: &str, file: &'static str,
+                                  line: uint) -> !; }
+    unsafe { rust_begin_unwind(msg, file, line) }
+}
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index e6fddd5f64e..a0938c83eca 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -21,6 +21,8 @@
 #![feature(globs, macro_rules, managed_boxes)]
 #![deny(missing_doc)]
 
+mod macros;
+
 #[path = "num/float_macros.rs"] mod float_macros;
 #[path = "num/int_macros.rs"]   mod int_macros;
 #[path = "num/uint_macros.rs"]  mod uint_macros;
@@ -75,7 +77,11 @@ pub mod slice;
 pub mod str;
 pub mod tuple;
 
-// FIXME: this module should not exist
+mod failure;
+
+// FIXME: this module should not exist. Once owned allocations are no longer a
+//        language type, this module can move outside to the owned allocation
+//        crate.
 mod should_not_exist;
 
 mod std {
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
new file mode 100644
index 00000000000..50d5cd81ba0
--- /dev/null
+++ b/src/libcore/macros.rs
@@ -0,0 +1,38 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![macro_escape]
+
+/// Entry point of failure, for details, see std::macros
+#[macro_export]
+macro_rules! fail(
+    () => (
+        fail!("explicit failure")
+    );
+    ($msg:expr) => (
+        ::failure::begin_unwind($msg, file!(), line!())
+    );
+)
+
+/// Runtime assertion, for details see std::macros
+#[macro_export]
+macro_rules! assert(
+    ($cond:expr) => (
+        if !$cond {
+            fail!(concat!("assertion failed: ", stringify!($cond)))
+        }
+    );
+)
+
+/// Runtime assertion, disableable at compile time
+#[macro_export]
+macro_rules! debug_assert(
+    ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); })
+)
diff --git a/src/libcore/num/int_macros.rs b/src/libcore/num/int_macros.rs
index fc134df9b94..771d801dcb7 100644
--- a/src/libcore/num/int_macros.rs
+++ b/src/libcore/num/int_macros.rs
@@ -255,7 +255,7 @@ mod tests {
     fn test_overflows() {
         assert!(MAX > 0);
         assert!(MIN <= 0);
-        assert_eq!(MIN + MAX + 1, 0);
+        assert!(MIN + MAX + 1 == 0);
     }
 
     #[test]
@@ -265,25 +265,25 @@ mod tests {
 
     #[test]
     pub fn test_abs() {
-        assert_eq!((1 as $T).abs(), 1 as $T);
-        assert_eq!((0 as $T).abs(), 0 as $T);
-        assert_eq!((-1 as $T).abs(), 1 as $T);
+        assert!((1 as $T).abs() == 1 as $T);
+        assert!((0 as $T).abs() == 0 as $T);
+        assert!((-1 as $T).abs() == 1 as $T);
     }
 
     #[test]
     fn test_abs_sub() {
-        assert_eq!((-1 as $T).abs_sub(&(1 as $T)), 0 as $T);
-        assert_eq!((1 as $T).abs_sub(&(1 as $T)), 0 as $T);
-        assert_eq!((1 as $T).abs_sub(&(0 as $T)), 1 as $T);
-        assert_eq!((1 as $T).abs_sub(&(-1 as $T)), 2 as $T);
+        assert!((-1 as $T).abs_sub(&(1 as $T)) == 0 as $T);
+        assert!((1 as $T).abs_sub(&(1 as $T)) == 0 as $T);
+        assert!((1 as $T).abs_sub(&(0 as $T)) == 1 as $T);
+        assert!((1 as $T).abs_sub(&(-1 as $T)) == 2 as $T);
     }
 
     #[test]
     fn test_signum() {
-        assert_eq!((1 as $T).signum(), 1 as $T);
-        assert_eq!((0 as $T).signum(), 0 as $T);
-        assert_eq!((-0 as $T).signum(), 0 as $T);
-        assert_eq!((-1 as $T).signum(), -1 as $T);
+        assert!((1 as $T).signum() == 1 as $T);
+        assert!((0 as $T).signum() == 0 as $T);
+        assert!((-0 as $T).signum() == 0 as $T);
+        assert!((-1 as $T).signum() == -1 as $T);
     }
 
     #[test]
@@ -304,33 +304,33 @@ mod tests {
 
     #[test]
     fn test_bitwise() {
-        assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(&(0b1010 as $T)));
-        assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(&(0b1010 as $T)));
-        assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(&(0b1010 as $T)));
-        assert_eq!(0b1110 as $T, (0b0111 as $T).shl(&(1 as $T)));
-        assert_eq!(0b0111 as $T, (0b1110 as $T).shr(&(1 as $T)));
-        assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not());
+        assert!(0b1110 as $T == (0b1100 as $T).bitor(&(0b1010 as $T)));
+        assert!(0b1000 as $T == (0b1100 as $T).bitand(&(0b1010 as $T)));
+        assert!(0b0110 as $T == (0b1100 as $T).bitxor(&(0b1010 as $T)));
+        assert!(0b1110 as $T == (0b0111 as $T).shl(&(1 as $T)));
+        assert!(0b0111 as $T == (0b1110 as $T).shr(&(1 as $T)));
+        assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not());
     }
 
     #[test]
     fn test_count_ones() {
-        assert_eq!((0b0101100 as $T).count_ones(), 3);
-        assert_eq!((0b0100001 as $T).count_ones(), 2);
-        assert_eq!((0b1111001 as $T).count_ones(), 5);
+        assert!((0b0101100 as $T).count_ones() == 3);
+        assert!((0b0100001 as $T).count_ones() == 2);
+        assert!((0b1111001 as $T).count_ones() == 5);
     }
 
     #[test]
     fn test_count_zeros() {
-        assert_eq!((0b0101100 as $T).count_zeros(), BITS as $T - 3);
-        assert_eq!((0b0100001 as $T).count_zeros(), BITS as $T - 2);
-        assert_eq!((0b1111001 as $T).count_zeros(), BITS as $T - 5);
+        assert!((0b0101100 as $T).count_zeros() == BITS as $T - 3);
+        assert!((0b0100001 as $T).count_zeros() == BITS as $T - 2);
+        assert!((0b1111001 as $T).count_zeros() == BITS as $T - 5);
     }
 
     #[test]
     fn test_signed_checked_div() {
-        assert_eq!(10i.checked_div(&2), Some(5));
-        assert_eq!(5i.checked_div(&0), None);
-        assert_eq!(int::MIN.checked_div(&-1), None);
+        assert!(10i.checked_div(&2) == Some(5));
+        assert!(5i.checked_div(&0) == None);
+        assert!(int::MIN.checked_div(&-1) == None);
     }
 }
 
diff --git a/src/libcore/num/uint_macros.rs b/src/libcore/num/uint_macros.rs
index 3ef785a0462..12aaf41b196 100644
--- a/src/libcore/num/uint_macros.rs
+++ b/src/libcore/num/uint_macros.rs
@@ -192,7 +192,7 @@ mod tests {
     fn test_overflows() {
         assert!(MAX > 0);
         assert!(MIN <= 0);
-        assert_eq!(MIN + MAX + 1, 0);
+        assert!(MIN + MAX + 1 == 0);
     }
 
     #[test]
@@ -202,32 +202,32 @@ mod tests {
 
     #[test]
     fn test_bitwise() {
-        assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(&(0b1010 as $T)));
-        assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(&(0b1010 as $T)));
-        assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(&(0b1010 as $T)));
-        assert_eq!(0b1110 as $T, (0b0111 as $T).shl(&(1 as $T)));
-        assert_eq!(0b0111 as $T, (0b1110 as $T).shr(&(1 as $T)));
-        assert_eq!(MAX - (0b1011 as $T), (0b1011 as $T).not());
+        assert!(0b1110 as $T == (0b1100 as $T).bitor(&(0b1010 as $T)));
+        assert!(0b1000 as $T == (0b1100 as $T).bitand(&(0b1010 as $T)));
+        assert!(0b0110 as $T == (0b1100 as $T).bitxor(&(0b1010 as $T)));
+        assert!(0b1110 as $T == (0b0111 as $T).shl(&(1 as $T)));
+        assert!(0b0111 as $T == (0b1110 as $T).shr(&(1 as $T)));
+        assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not());
     }
 
     #[test]
     fn test_count_ones() {
-        assert_eq!((0b0101100 as $T).count_ones(), 3);
-        assert_eq!((0b0100001 as $T).count_ones(), 2);
-        assert_eq!((0b1111001 as $T).count_ones(), 5);
+        assert!((0b0101100 as $T).count_ones() == 3);
+        assert!((0b0100001 as $T).count_ones() == 2);
+        assert!((0b1111001 as $T).count_ones() == 5);
     }
 
     #[test]
     fn test_count_zeros() {
-        assert_eq!((0b0101100 as $T).count_zeros(), BITS as $T - 3);
-        assert_eq!((0b0100001 as $T).count_zeros(), BITS as $T - 2);
-        assert_eq!((0b1111001 as $T).count_zeros(), BITS as $T - 5);
+        assert!((0b0101100 as $T).count_zeros() == BITS as $T - 3);
+        assert!((0b0100001 as $T).count_zeros() == BITS as $T - 2);
+        assert!((0b1111001 as $T).count_zeros() == BITS as $T - 5);
     }
 
     #[test]
     fn test_unsigned_checked_div() {
-        assert_eq!(10u.checked_div(&2), Some(5));
-        assert_eq!(5u.checked_div(&0), None);
+        assert!(10u.checked_div(&2) == Some(5));
+        assert!(5u.checked_div(&0) == None);
     }
 }
 
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index e79e3056838..5b9c314d42b 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -70,7 +70,7 @@ use self::task::{Task, BlockedTask};
 pub use self::util::default_sched_threads;
 
 // Export unwinding facilities used by the failure macros
-pub use self::unwind::{begin_unwind, begin_unwind_raw, begin_unwind_fmt};
+pub use self::unwind::{begin_unwind, begin_unwind_fmt};
 
 pub use self::util::{Stdio, Stdout, Stderr};
 
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
index 3ba97f381ab..5f3731eb819 100644
--- a/src/libstd/rt/unwind.rs
+++ b/src/libstd/rt/unwind.rs
@@ -58,7 +58,6 @@
 // Currently Rust uses unwind runtime provided by libgcc.
 
 use any::{Any, AnyRefExt};
-use c_str::CString;
 use cast;
 use fmt;
 use kinds::Send;
@@ -298,42 +297,23 @@ pub mod eabi {
 }
 
 #[cold]
-#[lang="fail_"]
+#[no_mangle]
 #[cfg(not(test))]
-pub fn fail_(expr: *u8, file: *u8, line: uint) -> ! {
-    begin_unwind_raw(expr, file, line);
-}
-
-#[cold]
-#[lang="fail_bounds_check"]
-#[cfg(not(test))]
-pub fn fail_bounds_check(file: *u8, line: uint, index: uint, len: uint) -> ! {
-    use c_str::ToCStr;
+pub extern fn rust_fail_bounds_check(file: *u8, line: uint,
+                                     index: uint, len: uint) -> ! {
+    use str::raw::c_str_to_static_slice;
 
     let msg = format!("index out of bounds: the len is {} but the index is {}",
                       len as uint, index as uint);
-    msg.with_c_str(|buf| fail_(buf as *u8, file, line))
+    begin_unwind(msg, unsafe { c_str_to_static_slice(file as *i8) }, line)
 }
 
-/// This is the entry point of unwinding for things like lang items and such.
-/// The arguments are normally generated by the compiler, and need to
-/// have static lifetimes.
-#[inline(never)] #[cold] // this is the slow path, please never inline this
-pub fn begin_unwind_raw(msg: *u8, file: *u8, line: uint) -> ! {
-    use libc::c_char;
-    #[inline]
-    fn static_char_ptr(p: *u8) -> &'static str {
-        let s = unsafe { CString::new(p as *c_char, false) };
-        match s.as_str() {
-            Some(s) => unsafe { cast::transmute::<&str, &'static str>(s) },
-            None => rtabort!("message wasn't utf8?")
-        }
-    }
-
-    let msg = static_char_ptr(msg);
-    let file = static_char_ptr(file);
-
-    begin_unwind(msg, file, line as uint)
+// Entry point of failure from the libcore crate
+#[no_mangle]
+#[cfg(not(test))]
+pub extern fn rust_begin_unwind(msg: &str, file: &'static str, line: uint) -> ! {
+    use str::StrAllocating;
+    begin_unwind(msg.to_owned(), file, line)
 }
 
 /// The entry point for unwinding with a formatted message.