diff options
| -rw-r--r-- | src/libcore/char.rs | 4 | ||||
| -rw-r--r-- | src/libcore/failure.rs | 54 | ||||
| -rw-r--r-- | src/libcore/lib.rs | 8 | ||||
| -rw-r--r-- | src/libcore/macros.rs | 38 | ||||
| -rw-r--r-- | src/libcore/num/int_macros.rs | 54 | ||||
| -rw-r--r-- | src/libcore/num/uint_macros.rs | 30 | ||||
| -rw-r--r-- | src/libstd/rt/mod.rs | 2 | ||||
| -rw-r--r-- | src/libstd/rt/unwind.rs | 42 |
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. |
