Skip to content

Commit e1be9ae

Browse files
committed
Made fail! and assert! accept both &'static str and ~str, as well as a fmt! like format list.
Unwinding through macros now happens as a call to the trait function `FailWithCause::fail_with()`, which consumes self, allowing to use a more generic failure object in the future.
1 parent 1d53bab commit e1be9ae

File tree

9 files changed

+90
-26
lines changed

9 files changed

+90
-26
lines changed

src/libcore/sys.rs

+46-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,42 @@ pub fn log_str<T>(t: &T) -> ~str {
165165
}
166166
}
167167

168-
/** Initiate task failure */
168+
/// Trait for initiating task failure.
169+
pub trait FailWithCause {
170+
/// Fail the current task, taking ownership of `cause`
171+
fn fail_with(cause: Self, file: &'static str, line: uint) -> !;
172+
}
173+
174+
impl FailWithCause for ~str {
175+
fn fail_with(cause: ~str, file: &'static str, line: uint) -> ! {
176+
do str::as_buf(cause) |msg_buf, _msg_len| {
177+
do str::as_buf(file) |file_buf, _file_len| {
178+
unsafe {
179+
let msg_buf = cast::transmute(msg_buf);
180+
let file_buf = cast::transmute(file_buf);
181+
begin_unwind_(msg_buf, file_buf, line as libc::size_t)
182+
}
183+
}
184+
}
185+
}
186+
}
187+
188+
impl FailWithCause for &'static str {
189+
fn fail_with(cause: &'static str, file: &'static str, line: uint) -> ! {
190+
do str::as_buf(cause) |msg_buf, _msg_len| {
191+
do str::as_buf(file) |file_buf, _file_len| {
192+
unsafe {
193+
let msg_buf = cast::transmute(msg_buf);
194+
let file_buf = cast::transmute(file_buf);
195+
begin_unwind_(msg_buf, file_buf, line as libc::size_t)
196+
}
197+
}
198+
}
199+
}
200+
}
201+
202+
// NOTE: remove function after snapshot
203+
#[cfg(stage0)]
169204
pub fn begin_unwind(msg: ~str, file: ~str, line: uint) -> ! {
170205
do str::as_buf(msg) |msg_buf, _msg_len| {
171206
do str::as_buf(file) |file_buf, _file_len| {
@@ -187,6 +222,8 @@ pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! {
187222
}
188223
}
189224

225+
// NOTE: remove function after snapshot
226+
#[cfg(stage0)]
190227
pub fn fail_assert(msg: &str, file: &str, line: uint) -> ! {
191228
let (msg, file) = (msg.to_owned(), file.to_owned());
192229
begin_unwind(~"assertion failed: " + msg, file, line)
@@ -297,6 +334,14 @@ mod tests {
297334
assert!(new_f(20) == 30);
298335
}
299336
}
337+
338+
#[test]
339+
#[should_fail]
340+
fn fail_static() { FailWithCause::fail_with("cause", file!(), line!()) }
341+
342+
#[test]
343+
#[should_fail]
344+
fn fail_owned() { FailWithCause::fail_with(~"cause", file!(), line!()) }
300345
}
301346

302347
// Local Variables:

src/libsyntax/ext/auto_encode.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1101,7 +1101,7 @@ fn mk_enum_deser_body(
11011101
};
11021102
11031103
let quoted_expr = copy quote_expr!(
1104-
::core::sys::begin_unwind(~"explicit failure", ~"empty", 1);
1104+
::core::sys::FailWithCause::fail_with("explicit failure", "empty", 1);
11051105
).node;
11061106
11071107
let impossible_case = ast::arm {

src/libsyntax/ext/build.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -474,11 +474,12 @@ pub fn mk_unreachable(cx: @ext_ctxt, span: span) -> @ast::expr {
474474
~[
475475
cx.ident_of(~"core"),
476476
cx.ident_of(~"sys"),
477-
cx.ident_of(~"begin_unwind"),
477+
cx.ident_of(~"FailWithCause"),
478+
cx.ident_of(~"fail_with"),
478479
],
479480
~[
480-
mk_uniq_str(cx, span, ~"internal error: entered unreachable code"),
481-
mk_uniq_str(cx, span, loc.file.name),
481+
mk_base_str(cx, span, ~"internal error: entered unreachable code"),
482+
mk_base_str(cx, span, loc.file.name),
482483
mk_uint(cx, span, loc.line),
483484
]
484485
)

src/libsyntax/ext/expand.rs

+29-13
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ pub fn core_macros() -> ~str {
415415
__log(1u32, fmt!( $($arg),+ ))
416416
)
417417
)
418+
418419
macro_rules! warn (
419420
($arg:expr) => (
420421
__log(2u32, fmt!( \"%?\", $arg ))
@@ -423,6 +424,7 @@ pub fn core_macros() -> ~str {
423424
__log(2u32, fmt!( $($arg),+ ))
424425
)
425426
)
427+
426428
macro_rules! info (
427429
($arg:expr) => (
428430
__log(3u32, fmt!( \"%?\", $arg ))
@@ -431,6 +433,7 @@ pub fn core_macros() -> ~str {
431433
__log(3u32, fmt!( $($arg),+ ))
432434
)
433435
)
436+
434437
macro_rules! debug (
435438
($arg:expr) => (
436439
__log(4u32, fmt!( \"%?\", $arg ))
@@ -441,35 +444,48 @@ pub fn core_macros() -> ~str {
441444
)
442445

443446
macro_rules! fail(
444-
($msg: expr) => (
445-
::core::sys::begin_unwind($msg, file!().to_owned(), line!())
446-
);
447447
() => (
448-
fail!(~\"explicit failure\")
448+
fail!(\"explicit failure\")
449+
);
450+
($msg:expr) => (
451+
::core::sys::FailWithCause::fail_with($msg, file!(), line!())
452+
);
453+
($( $arg:expr ),+) => (
454+
::core::sys::FailWithCause::fail_with(fmt!( $($arg),+ ), file!(), line!())
449455
)
450456
)
451457

452458
macro_rules! assert(
453459
($cond:expr) => {
454460
if !$cond {
455-
::core::sys::fail_assert(stringify!($cond), file!(), line!())
461+
::core::sys::FailWithCause::fail_with(
462+
~\"assertion failed: \" + stringify!($cond), file!(), line!())
456463
}
457464
};
458465
($cond:expr, $msg:expr) => {
459466
if !$cond {
460-
::core::sys::fail_assert($msg, file!(), line!())
467+
::core::sys::FailWithCause::fail_with($msg, file!(), line!())
468+
}
469+
};
470+
($cond:expr, $( $arg:expr ),+) => {
471+
if !$cond {
472+
::core::sys::FailWithCause::fail_with(fmt!( $($arg),+ ), file!(), line!())
461473
}
462474
}
463475
)
464476

465477
macro_rules! assert_eq (
466-
($given:expr , $expected:expr) =>
467-
({let given_val = $given;
468-
let expected_val = $expected;
469-
// check both directions of equality....
470-
if !((given_val == expected_val) && (expected_val == given_val)) {
471-
fail!(fmt!(\"expected: %?, given: %?\",expected_val,given_val));
472-
}}))
478+
($given:expr , $expected:expr) => (
479+
{
480+
let given_val = $given;
481+
let expected_val = $expected;
482+
// check both directions of equality....
483+
if !((given_val == expected_val) && (expected_val == given_val)) {
484+
fail!(fmt!(\"left: %? != right: %?\", given_val, expected_val));
485+
}
486+
}
487+
)
488+
)
473489

474490
macro_rules! condition (
475491

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// error-pattern:illegal borrow: borrowed value does not live long enough
2+
3+
fn main() {
4+
let v = ~"test";
5+
let sslice = str::slice(v, 0, v.len());
6+
fail!(sslice);
7+
}

src/test/compile-fail/die-not-unique.rs

-5
This file was deleted.

src/test/compile-fail/fail-expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// error-pattern:mismatched types
11+
// error-pattern:failed to find an implementation of trait core::sys::FailWithCause for int
1212

1313
fn main() { fail!(5); }

src/test/compile-fail/fail-type-err.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// error-pattern:expected `~str` but found `~[int]`
11+
// error-pattern:failed to find an implementation of trait core::sys::FailWithCause for ~[int]
1212
fn main() { fail!(~[0i]); }

src/test/run-fail/assert-eq-macro-fail.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// error-pattern:expected: 15, given: 14
1+
// error-pattern:left: 14 != right: 15
22

33
#[deriving(Eq)]
44
struct Point { x : int }

0 commit comments

Comments
 (0)