Update infrastructure for fail -> panic

This includes updating the language items and marking what needs to
change after a snapshot.

If you do not use the standard library, the language items you need to
implement have changed. For example:

```rust
 #[lang = "fail_fmt"] fn fail_fmt() -> ! { loop {} }
```

is now

```rust
 #[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
```

Related, lesser-implemented language items `fail` and
`fail_bounds_check` have become `panic` and `panic_bounds_check`, as
well. These are implemented by `libcore`, so it is unlikely (though
possible!) that these two renamings will affect you.

[breaking-change]

Fix test suite
This commit is contained in:
Steve Klabnik 2014-10-28 14:07:33 -04:00
parent 7828c3dd28
commit 6ac7fc73f5
40 changed files with 104 additions and 60 deletions

View File

@ -462,7 +462,7 @@ fn start(_argc: int, _argv: *const *const u8) -> int {
// provided by libstd.
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "fail_fmt"] fn fail_fmt() -> ! { loop {} }
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
# // fn main() {} tricked you, rustdoc!
```
@ -485,7 +485,7 @@ pub extern fn main(argc: int, argv: *const *const u8) -> int {
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "fail_fmt"] fn fail_fmt() -> ! { loop {} }
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
# // fn main() {} tricked you, rustdoc!
```
@ -505,7 +505,7 @@ failure mechanisms of the compiler. This is often mapped to GCC's
personality function (see the
[libstd implementation](std/rt/unwind/index.html) for more
information), but crates which do not trigger a panic can be assured
that this function is never called. The final function, `fail_fmt`, is
that this function is never called. The final function, `panic_fmt`, is
also used by the failure mechanisms of the compiler.
## Using libcore
@ -565,8 +565,8 @@ pub extern fn dot_product(a: *const u32, a_len: u32,
return ret;
}
#[lang = "fail_fmt"]
extern fn fail_fmt(args: &core::fmt::Arguments,
#[lang = "panic_fmt"]
extern fn panic_fmt(args: &core::fmt::Arguments,
file: &str,
line: uint) -> ! {
loop {}
@ -579,9 +579,9 @@ extern fn fail_fmt(args: &core::fmt::Arguments,
```
Note that there is one extra lang item here which differs from the examples
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
above, `panic_fmt`. This must be defined by consumers of libcore because the
core library declares panics, but it does not define it. The `panic_fmt`
lang item is this crate's definition of panic, and it must be guaranteed to
never return.
As can be seen in this example, the core library is intended to provide the
@ -686,7 +686,7 @@ fn main(argc: int, argv: *const *const u8) -> int {
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "fail_fmt"] fn fail_fmt() -> ! { loop {} }
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
```
Note the use of `abort`: the `exchange_malloc` lang item is assumed to

View File

@ -33,6 +33,49 @@
use fmt;
use intrinsics;
// NOTE(stage0): remove after a snapshot
#[cfg(stage0)]
#[cold] #[inline(never)] // this is the slow path, always
#[lang="fail"]
pub fn panic(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
let (expr, file, line) = *expr_file_line;
let ref file_line = (file, line);
format_args!(|args| -> () {
panic_fmt(args, file_line);
}, "{}", expr);
unsafe { intrinsics::abort() }
}
// NOTE(stage0): remove after a snapshot
#[cfg(stage0)]
#[cold] #[inline(never)]
#[lang="fail_bounds_check"]
fn panic_bounds_check(file_line: &(&'static str, uint),
index: uint, len: uint) -> ! {
format_args!(|args| -> () {
panic_fmt(args, file_line);
}, "index out of bounds: the len is {} but the index is {}", len, index);
unsafe { intrinsics::abort() }
}
// NOTE(stage0): remove after a snapshot
#[cfg(stage0)]
#[cold] #[inline(never)]
pub fn panic_fmt(fmt: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
#[allow(ctypes)]
extern {
#[lang = "fail_fmt"]
fn panic_impl(fmt: &fmt::Arguments, file: &'static str,
line: uint) -> !;
}
let (file, line) = *file_line;
unsafe { panic_impl(fmt, file, line) }
}
// NOTE(stage0): remove cfg after a snapshot
#[cfg(not(stage0))]
#[cold] #[inline(never)] // this is the slow path, always
#[lang="panic"]
pub fn panic(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
@ -45,6 +88,8 @@ pub fn panic(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
unsafe { intrinsics::abort() }
}
// NOTE(stage0): remove cfg after a snapshot
#[cfg(not(stage0))]
#[cold] #[inline(never)]
#[lang="panic_bounds_check"]
fn panic_bounds_check(file_line: &(&'static str, uint),
@ -55,6 +100,8 @@ fn panic_bounds_check(file_line: &(&'static str, uint),
unsafe { intrinsics::abort() }
}
// NOTE(stage0): remove cfg after a snapshot
#[cfg(not(stage0))]
#[cold] #[inline(never)]
pub fn panic_fmt(fmt: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
#[allow(ctypes)]

View File

@ -11,7 +11,7 @@
use llvm::*;
use driver::config::FullDebugInfo;
use middle::def;
use middle::lang_items::{FailFnLangItem, FailBoundsCheckFnLangItem};
use middle::lang_items::{PanicFnLangItem, PanicBoundsCheckFnLangItem};
use middle::trans::_match;
use middle::trans::adt;
use middle::trans::base::*;
@ -498,7 +498,7 @@ pub fn trans_fail<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let expr_file_line_const = C_struct(ccx, &[v_str, filename, line], false);
let expr_file_line = consts::const_addr_of(ccx, expr_file_line_const, ast::MutImmutable);
let args = vec!(expr_file_line);
let did = langcall(bcx, Some(sp), "", FailFnLangItem);
let did = langcall(bcx, Some(sp), "", PanicFnLangItem);
let bcx = callee::trans_lang_call(bcx,
did,
args.as_slice(),
@ -525,7 +525,7 @@ pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let file_line_const = C_struct(ccx, &[filename, line], false);
let file_line = consts::const_addr_of(ccx, file_line_const, ast::MutImmutable);
let args = vec!(file_line, index, len);
let did = langcall(bcx, Some(sp), "", FailBoundsCheckFnLangItem);
let did = langcall(bcx, Some(sp), "", PanicBoundsCheckFnLangItem);
let bcx = callee::trans_lang_call(bcx,
did,
args.as_slice(),

View File

@ -497,6 +497,14 @@ pub extern fn rust_begin_unwind(msg: &fmt::Arguments,
begin_unwind_fmt(msg, &(file, line))
}
// NOTE(stage0): remove after a snapshot
#[cfg(not(test))]
#[lang = "fail_fmt"]
pub extern fn rust_fail_begin_unwind(msg: &fmt::Arguments,
file: &'static str, line: uint) -> ! {
rust_begin_unwind(msg, file, line)
}
/// The entry point for unwinding with a formatted message.
///
/// This is designed to reduce the amount of code required at the call

View File

@ -14,8 +14,8 @@
#[lang="sized"]
pub trait Sized for Sized? {}
#[lang="fail"]
fn fail(_: &(&'static str, &'static str, uint)) -> ! { loop {} }
#[lang="panic"]
fn panic(_: &(&'static str, &'static str, uint)) -> ! { loop {} }
#[lang = "stack_exhausted"]
extern fn stack_exhausted() {}

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn foo() -> ! { fail!("quux"); }
fn foo() -> ! { panic!("quux"); }
fn main() {
foo() //~ ERROR the type of this value must be known in this context
==

View File

@ -9,6 +9,6 @@
// except according to those terms.
fn main() {
&fail!()
&panic!()
//~^ ERROR mismatched types: expected `()`, found `&<generic #2>` (expected (), found &-ptr)
}

View File

@ -9,7 +9,7 @@
// except according to those terms.
// aux-build:weak-lang-items.rs
// error-pattern: language item required, but not found: `fail_fmt`
// error-pattern: language item required, but not found: `panic_fmt`
// error-pattern: language item required, but not found: `stack_exhausted`
// error-pattern: language item required, but not found: `eh_personality`

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:failed at 'assertion failed: false'
// error-pattern:panicked at 'assertion failed: false'
fn main() {
assert!(false);

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:failed at 'test-assert-fmt 42 rust'
// error-pattern:panicked at 'test-assert-fmt 42 rust'
fn main() {
assert!(false, "test-assert-fmt {} {}", 42i, "rust");

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:failed at 'test-assert-owned'
// error-pattern:panicked at 'test-assert-owned'
fn main() {
assert!(false, "test-assert-owned".to_string());

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:failed at 'test-assert-static'
// error-pattern:panicked at 'test-assert-static'
fn main() {
assert!(false, "test-assert-static");

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:explicit failure
// error-pattern:explicit panic
trait Foo {
fn foo(self, x: int);

View File

@ -8,10 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:explicit panic
// error-pattern:explicit failure
fn f() -> ! { panic!() }
fn main() { f(); }

View File

@ -8,10 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:explicit panic
// error-pattern:explicit failure
fn f() -> ! { panic!() }
fn g() -> int { let x = if true { f() } else { 10 }; return x; }

View File

@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:explicit panic
// error-pattern:explicit failure
fn main() { let _x = if false { 0i } else if true { panic!() } else { 10i }; }

View File

@ -8,10 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:explicit panic
// error-pattern:explicit failure
fn f() -> ! { panic!() }
fn g() -> int { let x = match true { true => { f() } false => { 10 } }; return x; }

View File

@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:explicit panic
// error-pattern:explicit failure
fn main() { let _x = match true { false => { 0i } true => { panic!() } }; }

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:failed at 'Box<Any>'
// error-pattern:panicked at 'Box<Any>'
fn main() {
panic!(box 612_i64);

View File

@ -8,8 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:failed at 'Box<Any>'
// error-pattern:panicked at 'Box<Any>'
fn main() {
panic!(box 413i as Box<::std::any::Any+Send>);

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:failed at 'explicit failure'
// error-pattern:panicked at 'explicit panic'
fn main() {
panic!();

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:failed at 'test-fail-fmt 42 rust'
// error-pattern:panicked at 'test-fail-fmt 42 rust'
fn main() {
panic!("test-fail-fmt {} {}", 42i, "rust");

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:failed at 'test-fail-owned'
// error-pattern:panicked at 'test-fail-owned'
fn main() {
panic!("test-fail-owned");

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:failed at 'test-fail-static'
// error-pattern:panicked at 'test-fail-static'
fn main() {
panic!("test-fail-static");

View File

@ -12,7 +12,7 @@
// Previously failed formating invalid utf8.
// cc #16877
// error-pattern:failed at 'hello<6C>'
// error-pattern:panicked at 'hello<6C>'
struct Foo;
impl std::fmt::Show for Foo {

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:task '<unnamed>' failed at 'test'
// error-pattern:task '<unnamed>' panicked at 'test'
use std::task;

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:task 'owned name' failed at 'test'
// error-pattern:task 'owned name' panicked at 'test'
use std::task::TaskBuilder;

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:task 'send name' failed at 'test'
// error-pattern:task 'send name' panicked at 'test'
fn main() {
let r: Result<int,_> =

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:task 'static name' failed at 'test'
// error-pattern:task 'static name' panicked at 'test'
fn main() {
let r: Result<int,_> =

View File

@ -14,7 +14,7 @@
//
// Expanded pretty printing causes resolve conflicts.
// error-pattern:fail works
// error-pattern:panic works
#![feature(globs)]
use std::*;

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:explicit failure
// error-pattern:explicit panic
pub fn main() {
panic!(); println!("{}", 1i);

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:explicit failure
// error-pattern:explicit panic
use std::sync::Arc;

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:task '<main>' failed at
// error-pattern:task '<main>' panicked at
fn main() {
panic!()

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:explicit failure
// error-pattern:explicit panic
#![allow(unreachable_code)]
#![allow(unused_variable)]

View File

@ -9,7 +9,7 @@
// except according to those terms.
// ignore-android (FIXME #11419)
// error-pattern:explicit failure
// error-pattern:explicit panic
extern crate native;

View File

@ -9,7 +9,7 @@
// except according to those terms.
// check-stdout
// error-pattern:task 'test_foo' failed at
// error-pattern:task 'test_foo' panicked at
// compile-flags: --test
// ignore-pretty: does not work well with `--test`

View File

@ -8,5 +8,5 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern: fail
// error-pattern: panic
fn main() { box panic!(); }

View File

@ -19,4 +19,4 @@ pub extern fn bar() {}
#[lang = "stack_exhausted"] fn stack_exhausted() {}
#[lang = "eh_personality"] fn eh_personality() {}
#[lang = "fail_fmt"] fn fail_fmt() -> ! { loop {} }
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }

View File

@ -19,4 +19,4 @@ pub extern fn foo() {}
#[lang = "stack_exhausted"] fn stack_exhausted() {}
#[lang = "eh_personality"] fn eh_personality() {}
#[lang = "fail_fmt"] fn fail_fmt() -> ! { loop {} }
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }

View File

@ -22,7 +22,7 @@ extern "rust-intrinsic" { fn transmute<T, U>(t: T) -> U; }
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "fail_fmt"] fn fail_fmt() -> ! { loop {} }
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
#[start]
#[no_stack_check]