Skip to content

Commit c255568

Browse files
committed
core: Implement unwrap()/unwrap_err() on Result
Now that std::fmt is in libcore, it's possible to implement this as an inherit method rather than through extension traits. This commit also tweaks the failure interface of libcore to libstd to what it should be, one method taking &fmt::Arguments
1 parent cf06193 commit c255568

File tree

6 files changed

+66
-348
lines changed

6 files changed

+66
-348
lines changed

src/libcore/failure.rs

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,28 @@
99
// except according to those terms.
1010

1111
//! Failure support for libcore
12+
//!
13+
//! The core library cannot define failure, but it does *declare* failure. This
14+
//! means that the functions inside of libcore are allowed to fail, but to be
15+
//! useful an upstream crate must define failure for libcore to use. The current
16+
//! interface for failure is:
17+
//!
18+
//! fn begin_unwind(fmt: &fmt::Arguments, file: &str, line: uint) -> !;
19+
//!
20+
//! This definition allows for failing with any general message, but it does not
21+
//! allow for failing with a `~Any` value. The reason for this is that libcore
22+
//! is not allowed to allocate.
23+
//!
24+
//! This module contains a few other failure functions, but these are just the
25+
//! necessary lang items for the compiler. All failure is funneled through this
26+
//! one function. Currently, the actual symbol is declared in the standard
27+
//! library, but the location of this may change over time.
1228
1329
#![allow(dead_code, missing_doc)]
1430

1531
#[cfg(not(test))]
1632
use str::raw::c_str_to_static_slice;
17-
18-
// FIXME: Once std::fmt is in libcore, all of these functions should delegate
19-
// to a common failure function with this signature:
20-
//
21-
// extern {
22-
// fn rust_unwind(f: &fmt::Arguments, file: &str, line: uint) -> !;
23-
// }
24-
//
25-
// Each of these functions can create a temporary fmt::Arguments
26-
// structure to pass to this function.
33+
use fmt;
2734

2835
#[cold] #[inline(never)] // this is the slow path, always
2936
#[lang="fail_"]
@@ -32,24 +39,31 @@ fn fail_(expr: *u8, file: *u8, line: uint) -> ! {
3239
unsafe {
3340
let expr = c_str_to_static_slice(expr as *i8);
3441
let file = c_str_to_static_slice(file as *i8);
35-
begin_unwind(expr, file, line)
42+
format_args!(|args| -> () {
43+
begin_unwind(args, file, line);
44+
}, "{}", expr);
45+
46+
loop {}
3647
}
3748
}
3849

3950
#[cold]
4051
#[lang="fail_bounds_check"]
4152
#[cfg(not(test))]
4253
fn fail_bounds_check(file: *u8, line: uint, index: uint, len: uint) -> ! {
43-
#[allow(ctypes)]
44-
extern { fn rust_fail_bounds_check(file: *u8, line: uint,
45-
index: uint, len: uint,) -> !; }
46-
unsafe { rust_fail_bounds_check(file, line, index, len) }
54+
let file = unsafe { c_str_to_static_slice(file as *i8) };
55+
format_args!(|args| -> () {
56+
begin_unwind(args, file, line);
57+
}, "index out of bounds: the len is {} but the index is {}", len, index);
58+
loop {}
4759
}
4860

4961
#[cold]
50-
pub fn begin_unwind(msg: &str, file: &'static str, line: uint) -> ! {
62+
pub fn begin_unwind(fmt: &fmt::Arguments, file: &'static str, line: uint) -> ! {
63+
// FIXME: this should be a proper lang item, it should not just be some
64+
// undefined symbol sitting in the middle of nowhere.
5165
#[allow(ctypes)]
52-
extern { fn rust_begin_unwind(msg: &str, file: &'static str,
66+
extern { fn rust_begin_unwind(fmt: &fmt::Arguments, file: &'static str,
5367
line: uint) -> !; }
54-
unsafe { rust_begin_unwind(msg, file, line) }
68+
unsafe { rust_begin_unwind(fmt, file, line) }
5569
}

src/libcore/result.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@
268268
269269
use clone::Clone;
270270
use cmp::Eq;
271+
use fmt::Show;
271272
use iter::{Iterator, FromIterator};
272273
use option::{None, Option, Some};
273274

@@ -515,6 +516,34 @@ impl<T, E> Result<T, E> {
515516
}
516517
}
517518

519+
impl<T, E: Show> Result<T, E> {
520+
/// Unwraps a result, yielding the content of an `Ok`.
521+
///
522+
/// Fails if the value is an `Err`.
523+
#[inline]
524+
pub fn unwrap(self) -> T {
525+
match self {
526+
Ok(t) => t,
527+
Err(e) =>
528+
fail!("called `Result::unwrap()` on an `Err` value: {}", e)
529+
}
530+
}
531+
}
532+
533+
impl<T: Show, E> Result<T, E> {
534+
/// Unwraps a result, yielding the content of an `Err`.
535+
///
536+
/// Fails if the value is an `Ok`.
537+
#[inline]
538+
pub fn unwrap_err(self) -> E {
539+
match self {
540+
Ok(t) =>
541+
fail!("called `Result::unwrap_err()` on an `Ok` value: {}", t),
542+
Err(e) => e
543+
}
544+
}
545+
}
546+
518547
/////////////////////////////////////////////////////////////////////////////
519548
// Free functions
520549
/////////////////////////////////////////////////////////////////////////////

src/libstd/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ pub use core::mem;
153153
pub use core::ptr;
154154
pub use core::raw;
155155
pub use core::tuple;
156+
pub use core::result;
156157

157158
// Run tests with libgreen instead of libnative.
158159
//
@@ -218,7 +219,6 @@ pub mod hash;
218219

219220
/* Common data structures */
220221

221-
pub mod result;
222222
pub mod option;
223223

224224
/* Tasks and communication */

src/libstd/prelude.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,12 @@ pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, CloneableIte
6464
pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize};
6565
pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul};
6666
pub use num::{Signed, Unsigned};
67-
pub use num::{Primitive, Int, Float, ToPrimitive, FromPrimitive};
67+
pub use num::{Primitive, Int, Float, FloatMath, ToPrimitive, FromPrimitive};
6868
pub use option::Expect;
6969
pub use owned::Box;
7070
pub use path::{GenericPath, Path, PosixPath, WindowsPath};
7171
pub use ptr::RawPtr;
7272
pub use io::{Buffer, Writer, Reader, Seek};
73-
pub use result::{ResultUnwrap, ResultUnwrapErr};
7473
pub use str::{Str, StrVector, StrSlice, OwnedStr, IntoMaybeOwned};
7574
pub use str::{StrAllocating};
7675
pub use to_str::{ToStr, IntoStr};

0 commit comments

Comments
 (0)