Skip to content

Commit

Permalink
core: Move Option::expect to libstd from libcore
Browse files Browse the repository at this point in the history
See #14008 for more details
  • Loading branch information
alexcrichton committed May 7, 2014
1 parent 4a97441 commit 0d8f5fa
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 33 deletions.
24 changes: 0 additions & 24 deletions src/libcore/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,30 +230,6 @@ impl<T> Option<T> {
// Getting to contained values
/////////////////////////////////////////////////////////////////////////

/// Unwraps an option, yielding the content of a `Some`
///
/// # Failure
///
/// Fails if the value is a `None` with a custom failure message provided by `msg`.
#[inline]
#[cfg(not(test))]
pub fn expect(self, msg: &str) -> T {
match self {
Some(val) => val,
None => fail!(msg),
}
}

// FIXME: once std::fmt is in libcore, this extra variant should not be
// necessary.
#[cfg(test)]
pub fn expect(self, msg: &str) -> T {
match self {
Some(val) => val,
None => fail!("{}", msg),
}
}

/// Moves a value out of an option type and returns it, consuming the `Option`.
///
/// # Failure
Expand Down
10 changes: 5 additions & 5 deletions src/libcore/should_not_exist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ extern {
}

unsafe fn alloc(cap: uint) -> *mut Vec<()> {
let cap = cap.checked_add(&mem::size_of::<Vec<()>>()).expect("cap overflow");
let cap = cap.checked_add(&mem::size_of::<Vec<()>>()).unwrap();
let ret = malloc(cap) as *mut Vec<()>;
if ret.is_null() {
intrinsics::abort();
Expand Down Expand Up @@ -94,7 +94,7 @@ impl FromIterator<char> for ~str {
let amt = ch.encode_utf8(tmp);

if len + amt > cap {
cap = cap.checked_mul(&2).expect("cap overflow");
cap = cap.checked_mul(&2).unwrap();
if cap < len + amt {
cap = len + amt;
}
Expand Down Expand Up @@ -124,7 +124,7 @@ impl FromIterator<char> for ~str {
impl<'a> Add<&'a str,~str> for &'a str {
#[inline]
fn add(&self, rhs: & &'a str) -> ~str {
let amt = self.len().checked_add(&rhs.len()).expect("len overflow");
let amt = self.len().checked_add(&rhs.len()).unwrap();
unsafe {
let ptr = alloc(amt) as *mut Vec<u8>;
let base = &mut (*ptr).data as *mut _;
Expand Down Expand Up @@ -155,15 +155,15 @@ impl<A> FromIterator<A> for ~[A] {
fn from_iter<T: Iterator<A>>(mut iterator: T) -> ~[A] {
let (lower, _) = iterator.size_hint();
let cap = if lower == 0 {16} else {lower};
let mut cap = cap.checked_mul(&mem::size_of::<A>()).expect("cap overflow");
let mut cap = cap.checked_mul(&mem::size_of::<A>()).unwrap();
let mut len = 0;

unsafe {
let mut ptr = alloc(cap) as *mut Vec<A>;
let mut ret = cast::transmute(ptr);
for elt in iterator {
if len * mem::size_of::<A>() >= cap {
cap = cap.checked_mul(&2).expect("cap overflow");
cap = cap.checked_mul(&2).unwrap();
let ptr2 = alloc(cap) as *mut Vec<A>;
ptr::copy_nonoverlapping_memory(&mut (*ptr2).data,
&(*ptr).data,
Expand Down
1 change: 1 addition & 0 deletions src/libstd/io/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use comm::Receiver;
use io::IoResult;
use kinds::Send;
use owned::Box;
use option::Expect;
use rt::rtio::{IoFactory, LocalIo, RtioTimer};

/// A synchronous timer object
Expand Down
3 changes: 1 addition & 2 deletions src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ pub use core::default;
pub use core::intrinsics;
pub use core::iter;
pub use core::mem;
pub use core::option;
pub use core::ptr;
pub use core::raw;
pub use core::tuple;
Expand Down Expand Up @@ -221,7 +220,7 @@ pub mod hash;
/* Common data structures */

pub mod result;

pub mod option;

/* Tasks and communication */

Expand Down
167 changes: 167 additions & 0 deletions src/libstd/option.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
// 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.

//! Optional values
//!
//! Type `Option` represents an optional value: every `Option`
//! is either `Some` and contains a value, or `None`, and
//! does not. `Option` types are very common in Rust code, as
//! they have a number of uses:
//!
//! * Initial values
//! * Return values for functions that are not defined
//! over their entire input range (partial functions)
//! * Return value for otherwise reporting simple errors, where `None` is
//! returned on error
//! * Optional struct fields
//! * Struct fields that can be loaned or "taken"
//! * Optional function arguments
//! * Nullable pointers
//! * Swapping things out of difficult situations
//!
//! Options are commonly paired with pattern matching to query the presence
//! of a value and take action, always accounting for the `None` case.
//!
//! ```
//! # // FIXME This is not the greatest first example
//! // cow_says contains the word "moo"
//! let cow_says = Some("moo");
//! // dog_says does not contain a value
//! let dog_says: Option<&str> = None;
//!
//! // Pattern match to retrieve the value
//! match (cow_says, dog_says) {
//! (Some(cow_words), Some(dog_words)) => {
//! println!("Cow says {} and dog says {}!", cow_words, dog_words);
//! }
//! (Some(cow_words), None) => println!("Cow says {}", cow_words),
//! (None, Some(dog_words)) => println!("Dog says {}", dog_words),
//! (None, None) => println!("Cow and dog are suspiciously silent")
//! }
//! ```
//!
//
// FIXME: Show how `Option` is used in practice, with lots of methods
//
//! # Options and pointers ("nullable" pointers)
//!
//! Rust's pointer types must always point to a valid location; there are
//! no "null" pointers. Instead, Rust has *optional* pointers, like
//! the optional owned box, `Option<~T>`.
//!
//! The following example uses `Option` to create an optional box of
//! `int`. Notice that in order to use the inner `int` value first the
//! `check_optional` function needs to use pattern matching to
//! determine whether the box has a value (i.e. it is `Some(...)`) or
//! not (`None`).
//!
//! ```
//! let optional: Option<~int> = None;
//! check_optional(&optional);
//!
//! let optional: Option<~int> = Some(~9000);
//! check_optional(&optional);
//!
//! fn check_optional(optional: &Option<~int>) {
//! match *optional {
//! Some(ref p) => println!("have value {}", p),
//! None => println!("have no value")
//! }
//! }
//! ```
//!
//! This usage of `Option` to create safe nullable pointers is so
//! common that Rust does special optimizations to make the
//! representation of `Option<~T>` a single pointer. Optional pointers
//! in Rust are stored as efficiently as any other pointer type.
//!
//! # Examples
//!
//! Basic pattern matching on `Option`:
//!
//! ```
//! let msg = Some("howdy");
//!
//! // Take a reference to the contained string
//! match msg {
//! Some(ref m) => println!("{}", *m),
//! None => ()
//! }
//!
//! // Remove the contained string, destroying the Option
//! let unwrapped_msg = match msg {
//! Some(m) => m,
//! None => "default message"
//! };
//! ```
//!
//! Initialize a result to `None` before a loop:
//!
//! ```
//! enum Kingdom { Plant(uint, &'static str), Animal(uint, &'static str) }
//!
//! // A list of data to search through.
//! let all_the_big_things = [
//! Plant(250, "redwood"),
//! Plant(230, "noble fir"),
//! Plant(229, "sugar pine"),
//! Animal(25, "blue whale"),
//! Animal(19, "fin whale"),
//! Animal(15, "north pacific right whale"),
//! ];
//!
//! // We're going to search for the name of the biggest animal,
//! // but to start with we've just got `None`.
//! let mut name_of_biggest_animal = None;
//! let mut size_of_biggest_animal = 0;
//! for big_thing in all_the_big_things.iter() {
//! match *big_thing {
//! Animal(size, name) if size > size_of_biggest_animal => {
//! // Now we've found the name of some big animal
//! size_of_biggest_animal = size;
//! name_of_biggest_animal = Some(name);
//! }
//! Animal(..) | Plant(..) => ()
//! }
//! }
//!
//! match name_of_biggest_animal {
//! Some(name) => println!("the biggest animal is {}", name),
//! None => println!("there are no animals :(")
//! }
//! ```

use any::Any;
use kinds::Send;

pub use core::option::{Option, Some, None, Item, collect};

/// Extension trait for the `Option` type to add an `expect` method

// FIXME(#14008) should this trait even exist?
pub trait Expect<T> {
/// Unwraps an option, yielding the content of a `Some`
///
/// # Failure
///
/// Fails if the value is a `None` with a custom failure message provided by
/// `msg`.
fn expect<M: Any + Send>(self, m: M) -> T;
}

impl<T> Expect<T> for Option<T> {
#[inline]
fn expect<M: Any + Send>(self, msg: M) -> T {
match self {
Some(val) => val,
None => fail!(msg),
}
}
}
1 change: 1 addition & 0 deletions src/libstd/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize};
pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul};
pub use num::{Signed, Unsigned};
pub use num::{Primitive, Int, Float, ToPrimitive, FromPrimitive};
pub use option::Expect;
pub use owned::Box;
pub use path::{GenericPath, Path, PosixPath, WindowsPath};
pub use ptr::RawPtr;
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/rt/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//! Runtime environment settings

use from_str::from_str;
use option::{Some, None};
use option::{Some, None, Expect};
use os;

// Note that these are all accessed without any synchronization.
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use mem;
use num;
use num::{CheckedMul, CheckedAdd};
use ops::Drop;
use option::{None, Option, Some};
use option::{None, Option, Some, Expect};
use ptr::RawPtr;
use ptr;
use rt::global_heap::{malloc_raw, realloc_raw};
Expand Down

0 comments on commit 0d8f5fa

Please sign in to comment.