diff --git a/src/doc/guide-unsafe.md b/src/doc/guide-unsafe.md index 8c67634d57aec..ba79e828150e5 100644 --- a/src/doc/guide-unsafe.md +++ b/src/doc/guide-unsafe.md @@ -573,8 +573,8 @@ pub extern fn dot_product(a: *const u32, a_len: u32, return ret; } -#[lang = "begin_unwind"] -extern fn begin_unwind(args: &core::fmt::Arguments, +#[lang = "fail_fmt"] +extern fn fail_fmt(args: &core::fmt::Arguments, file: &str, line: uint) -> ! { loop {} @@ -587,8 +587,8 @@ extern fn begin_unwind(args: &core::fmt::Arguments, ``` Note that there is one extra lang item here which differs from the examples -above, `begin_unwind`. This must be defined by consumers of libcore because the -core library declares failure, but it does not define it. The `begin_unwind` +above, `fail_fmt`. This must be defined by consumers of libcore because the +core library declares failure, but it does not define it. The `fail_fmt` lang item is this crate's definition of failure, and it must be guaranteed to never return. @@ -706,7 +706,7 @@ Other features provided by lang items include: `==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all marked with lang items; those specific four are `eq`, `ord`, `deref`, and `add` respectively. -- stack unwinding and general failure; the `eh_personality`, `fail_` +- stack unwinding and general failure; the `eh_personality`, `fail` and `fail_bounds_checks` lang items. - the traits in `std::kinds` used to indicate types that satisfy various kinds; lang items `send`, `sync` and `copy`. diff --git a/src/libcore/failure.rs b/src/libcore/failure.rs index ac162c206c68c..f5f45b2f72e2a 100644 --- a/src/libcore/failure.rs +++ b/src/libcore/failure.rs @@ -16,7 +16,7 @@ //! interface for failure is: //! //! ```ignore -//! fn begin_unwind(fmt: &fmt::Arguments, &(&'static str, uint)) -> !; +//! fn fail_impl(fmt: &fmt::Arguments, &(&'static str, uint)) -> !; //! ``` //! //! This definition allows for failing with any general message, but it does not @@ -33,13 +33,28 @@ use fmt; use intrinsics; +// NOTE: remove after next snapshot +#[cfg(stage0)] #[cold] #[inline(never)] // this is the slow path, always #[lang="fail_"] fn fail_(expr_file_line: &(&'static str, &'static str, uint)) -> ! { let (expr, file, line) = *expr_file_line; let ref file_line = (file, line); format_args!(|args| -> () { - begin_unwind(args, file_line); + fail_fmt(args, file_line); + }, "{}", expr); + + unsafe { intrinsics::abort() } +} + +#[cfg(not(stage0))] +#[cold] #[inline(never)] // this is the slow path, always +#[lang="fail"] +fn fail(expr_file_line: &(&'static str, &'static str, uint)) -> ! { + let (expr, file, line) = *expr_file_line; + let ref file_line = (file, line); + format_args!(|args| -> () { + fail_fmt(args, file_line); }, "{}", expr); unsafe { intrinsics::abort() } @@ -50,25 +65,33 @@ fn fail_(expr_file_line: &(&'static str, &'static str, uint)) -> ! { fn fail_bounds_check(file_line: &(&'static str, uint), index: uint, len: uint) -> ! { format_args!(|args| -> () { - begin_unwind(args, file_line); + fail_fmt(args, file_line); }, "index out of bounds: the len is {} but the index is {}", len, index); unsafe { intrinsics::abort() } } #[cold] #[inline(never)] -pub fn begin_unwind_string(msg: &str, file: &(&'static str, uint)) -> ! { - format_args!(|fmt| begin_unwind(fmt, file), "{}", msg) +pub fn fail_str(msg: &str, file: &(&'static str, uint)) -> ! { + format_args!(|fmt| fail_fmt(fmt, file), "{}", msg) } #[cold] #[inline(never)] -pub fn begin_unwind(fmt: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! { +pub fn fail_fmt(fmt: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! { #[allow(ctypes)] extern { + + // NOTE: remove after next snapshot + #[cfg(stage0)] #[lang = "begin_unwind"] - fn begin_unwind(fmt: &fmt::Arguments, file: &'static str, + fn fail_impl(fmt: &fmt::Arguments, file: &'static str, line: uint) -> !; + + #[cfg(not(stage0))] + #[lang = "fail_fmt"] + fn fail_impl(fmt: &fmt::Arguments, file: &'static str, + line: uint) -> !; + } let (file, line) = *file_line; - unsafe { begin_unwind(fmt, file, line) } + unsafe { fail_impl(fmt, file, line) } } - diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index e846f8dbeb404..0f972a6702916 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -18,7 +18,7 @@ macro_rules! fail( ); ($msg:expr) => ({ static _FILE_LINE: (&'static str, uint) = (file!(), line!()); - ::core::failure::begin_unwind_string($msg, &_FILE_LINE) + ::core::failure::fail_str($msg, &_FILE_LINE) }); ($fmt:expr, $($arg:tt)*) => ({ // a closure can't have return type !, so we need a full @@ -40,7 +40,7 @@ macro_rules! fail( #[inline(always)] fn _run_fmt(fmt: &::std::fmt::Arguments) -> ! { static _FILE_LINE: (&'static str, uint) = (file!(), line!()); - ::core::failure::begin_unwind(fmt, &_FILE_LINE) + ::core::failure::fail_fmt(fmt, &_FILE_LINE) } format_args!(_run_fmt, $fmt, $($arg)*) }); diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index daba3b701c03b..50c92b45fdff4 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -264,7 +264,7 @@ lets_do_this! { StrEqFnLangItem, "str_eq", str_eq_fn; - // A number of failure-related lang items. The `fail_` item corresponds to + // A number of failure-related lang items. The `fail` item corresponds to // divide-by-zero and various failure cases with `match`. The // `fail_bounds_check` item is for indexing arrays. // @@ -273,9 +273,9 @@ lets_do_this! { // defined to use it, but a final product is required to define it // somewhere. Additionally, there are restrictions on crates that use a weak // lang item, but do not have it defined. - FailFnLangItem, "fail_", fail_fn; + FailFnLangItem, "fail", fail_fn; FailBoundsCheckFnLangItem, "fail_bounds_check", fail_bounds_check_fn; - BeginUnwindLangItem, "begin_unwind", begin_unwind; + FailFmtLangItem, "fail_fmt", fail_fmt; ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn; ExchangeFreeFnLangItem, "exchange_free", exchange_free_fn; diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index 81099da3fac05..79faf3aa147ed 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -118,7 +118,7 @@ impl<'a, 'v> Visitor<'v> for Context<'a> { ) ) weak_lang_items!( - begin_unwind, BeginUnwindLangItem, rust_begin_unwind; + fail_fmt, FailFmtLangItem, rust_begin_unwind; stack_exhausted, StackExhaustedLangItem, rust_stack_exhausted; eh_personality, EhPersonalityLangItem, rust_eh_personality; ) diff --git a/src/librustrt/unwind.rs b/src/librustrt/unwind.rs index acef05e08673b..034ed470c9752 100644 --- a/src/librustrt/unwind.rs +++ b/src/librustrt/unwind.rs @@ -488,7 +488,16 @@ pub mod eabi { } // Entry point of failure from the libcore crate -#[cfg(not(test))] +#[cfg(not(test), not(stage0))] +#[lang = "fail_fmt"] +pub extern fn rust_begin_unwind(msg: &fmt::Arguments, + file: &'static str, line: uint) -> ! { + begin_unwind_fmt(msg, &(file, line)) +} + +// +// Entry point of failure from the libcore crate +#[cfg(stage0, not(test))] #[lang = "begin_unwind"] pub extern fn rust_begin_unwind(msg: &fmt::Arguments, file: &'static str, line: uint) -> ! { diff --git a/src/test/auxiliary/lang-item-public.rs b/src/test/auxiliary/lang-item-public.rs index 5723b59a60b95..73bad01147240 100644 --- a/src/test/auxiliary/lang-item-public.rs +++ b/src/test/auxiliary/lang-item-public.rs @@ -11,7 +11,7 @@ #![no_std] #![feature(lang_items)] -#[lang="fail_"] +#[lang="fail"] fn fail(_: &(&'static str, &'static str, uint)) -> ! { loop {} } #[lang = "stack_exhausted"] diff --git a/src/test/compile-fail/lint-dead-code-1.rs b/src/test/compile-fail/lint-dead-code-1.rs index 3e563e9e13806..b7feea775cb43 100644 --- a/src/test/compile-fail/lint-dead-code-1.rs +++ b/src/test/compile-fail/lint-dead-code-1.rs @@ -108,5 +108,5 @@ fn g() { h(); } fn h() {} // Similarly, lang items are live -#[lang="fail_"] +#[lang="fail"] fn fail(_: *const u8, _: *const u8, _: uint) -> ! { loop {} } diff --git a/src/test/compile-fail/weak-lang-item.rs b/src/test/compile-fail/weak-lang-item.rs index 636adefb95e27..74ec56f7bd90a 100644 --- a/src/test/compile-fail/weak-lang-item.rs +++ b/src/test/compile-fail/weak-lang-item.rs @@ -9,7 +9,7 @@ // except according to those terms. // aux-build:weak-lang-items.rs -// error-pattern: language item required, but not found: `begin_unwind` +// error-pattern: language item required, but not found: `fail_fmt` // error-pattern: language item required, but not found: `stack_exhausted` // error-pattern: language item required, but not found: `eh_personality`