Skip to content

Commit 0d8f5fa

Browse files
committed
core: Move Option::expect to libstd from libcore
See #14008 for more details
1 parent 4a97441 commit 0d8f5fa

File tree

8 files changed

+177
-33
lines changed

8 files changed

+177
-33
lines changed

src/libcore/option.rs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -230,30 +230,6 @@ impl<T> Option<T> {
230230
// Getting to contained values
231231
/////////////////////////////////////////////////////////////////////////
232232

233-
/// Unwraps an option, yielding the content of a `Some`
234-
///
235-
/// # Failure
236-
///
237-
/// Fails if the value is a `None` with a custom failure message provided by `msg`.
238-
#[inline]
239-
#[cfg(not(test))]
240-
pub fn expect(self, msg: &str) -> T {
241-
match self {
242-
Some(val) => val,
243-
None => fail!(msg),
244-
}
245-
}
246-
247-
// FIXME: once std::fmt is in libcore, this extra variant should not be
248-
// necessary.
249-
#[cfg(test)]
250-
pub fn expect(self, msg: &str) -> T {
251-
match self {
252-
Some(val) => val,
253-
None => fail!("{}", msg),
254-
}
255-
}
256-
257233
/// Moves a value out of an option type and returns it, consuming the `Option`.
258234
///
259235
/// # Failure

src/libcore/should_not_exist.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ extern {
3434
}
3535

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

9696
if len + amt > cap {
97-
cap = cap.checked_mul(&2).expect("cap overflow");
97+
cap = cap.checked_mul(&2).unwrap();
9898
if cap < len + amt {
9999
cap = len + amt;
100100
}
@@ -124,7 +124,7 @@ impl FromIterator<char> for ~str {
124124
impl<'a> Add<&'a str,~str> for &'a str {
125125
#[inline]
126126
fn add(&self, rhs: & &'a str) -> ~str {
127-
let amt = self.len().checked_add(&rhs.len()).expect("len overflow");
127+
let amt = self.len().checked_add(&rhs.len()).unwrap();
128128
unsafe {
129129
let ptr = alloc(amt) as *mut Vec<u8>;
130130
let base = &mut (*ptr).data as *mut _;
@@ -155,15 +155,15 @@ impl<A> FromIterator<A> for ~[A] {
155155
fn from_iter<T: Iterator<A>>(mut iterator: T) -> ~[A] {
156156
let (lower, _) = iterator.size_hint();
157157
let cap = if lower == 0 {16} else {lower};
158-
let mut cap = cap.checked_mul(&mem::size_of::<A>()).expect("cap overflow");
158+
let mut cap = cap.checked_mul(&mem::size_of::<A>()).unwrap();
159159
let mut len = 0;
160160

161161
unsafe {
162162
let mut ptr = alloc(cap) as *mut Vec<A>;
163163
let mut ret = cast::transmute(ptr);
164164
for elt in iterator {
165165
if len * mem::size_of::<A>() >= cap {
166-
cap = cap.checked_mul(&2).expect("cap overflow");
166+
cap = cap.checked_mul(&2).unwrap();
167167
let ptr2 = alloc(cap) as *mut Vec<A>;
168168
ptr::copy_nonoverlapping_memory(&mut (*ptr2).data,
169169
&(*ptr).data,

src/libstd/io/timer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use comm::Receiver;
2121
use io::IoResult;
2222
use kinds::Send;
2323
use owned::Box;
24+
use option::Expect;
2425
use rt::rtio::{IoFactory, LocalIo, RtioTimer};
2526

2627
/// A synchronous timer object

src/libstd/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ pub use core::default;
149149
pub use core::intrinsics;
150150
pub use core::iter;
151151
pub use core::mem;
152-
pub use core::option;
153152
pub use core::ptr;
154153
pub use core::raw;
155154
pub use core::tuple;
@@ -221,7 +220,7 @@ pub mod hash;
221220
/* Common data structures */
222221

223222
pub mod result;
224-
223+
pub mod option;
225224

226225
/* Tasks and communication */
227226

src/libstd/option.rs

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! Optional values
12+
//!
13+
//! Type `Option` represents an optional value: every `Option`
14+
//! is either `Some` and contains a value, or `None`, and
15+
//! does not. `Option` types are very common in Rust code, as
16+
//! they have a number of uses:
17+
//!
18+
//! * Initial values
19+
//! * Return values for functions that are not defined
20+
//! over their entire input range (partial functions)
21+
//! * Return value for otherwise reporting simple errors, where `None` is
22+
//! returned on error
23+
//! * Optional struct fields
24+
//! * Struct fields that can be loaned or "taken"
25+
//! * Optional function arguments
26+
//! * Nullable pointers
27+
//! * Swapping things out of difficult situations
28+
//!
29+
//! Options are commonly paired with pattern matching to query the presence
30+
//! of a value and take action, always accounting for the `None` case.
31+
//!
32+
//! ```
33+
//! # // FIXME This is not the greatest first example
34+
//! // cow_says contains the word "moo"
35+
//! let cow_says = Some("moo");
36+
//! // dog_says does not contain a value
37+
//! let dog_says: Option<&str> = None;
38+
//!
39+
//! // Pattern match to retrieve the value
40+
//! match (cow_says, dog_says) {
41+
//! (Some(cow_words), Some(dog_words)) => {
42+
//! println!("Cow says {} and dog says {}!", cow_words, dog_words);
43+
//! }
44+
//! (Some(cow_words), None) => println!("Cow says {}", cow_words),
45+
//! (None, Some(dog_words)) => println!("Dog says {}", dog_words),
46+
//! (None, None) => println!("Cow and dog are suspiciously silent")
47+
//! }
48+
//! ```
49+
//!
50+
//
51+
// FIXME: Show how `Option` is used in practice, with lots of methods
52+
//
53+
//! # Options and pointers ("nullable" pointers)
54+
//!
55+
//! Rust's pointer types must always point to a valid location; there are
56+
//! no "null" pointers. Instead, Rust has *optional* pointers, like
57+
//! the optional owned box, `Option<~T>`.
58+
//!
59+
//! The following example uses `Option` to create an optional box of
60+
//! `int`. Notice that in order to use the inner `int` value first the
61+
//! `check_optional` function needs to use pattern matching to
62+
//! determine whether the box has a value (i.e. it is `Some(...)`) or
63+
//! not (`None`).
64+
//!
65+
//! ```
66+
//! let optional: Option<~int> = None;
67+
//! check_optional(&optional);
68+
//!
69+
//! let optional: Option<~int> = Some(~9000);
70+
//! check_optional(&optional);
71+
//!
72+
//! fn check_optional(optional: &Option<~int>) {
73+
//! match *optional {
74+
//! Some(ref p) => println!("have value {}", p),
75+
//! None => println!("have no value")
76+
//! }
77+
//! }
78+
//! ```
79+
//!
80+
//! This usage of `Option` to create safe nullable pointers is so
81+
//! common that Rust does special optimizations to make the
82+
//! representation of `Option<~T>` a single pointer. Optional pointers
83+
//! in Rust are stored as efficiently as any other pointer type.
84+
//!
85+
//! # Examples
86+
//!
87+
//! Basic pattern matching on `Option`:
88+
//!
89+
//! ```
90+
//! let msg = Some("howdy");
91+
//!
92+
//! // Take a reference to the contained string
93+
//! match msg {
94+
//! Some(ref m) => println!("{}", *m),
95+
//! None => ()
96+
//! }
97+
//!
98+
//! // Remove the contained string, destroying the Option
99+
//! let unwrapped_msg = match msg {
100+
//! Some(m) => m,
101+
//! None => "default message"
102+
//! };
103+
//! ```
104+
//!
105+
//! Initialize a result to `None` before a loop:
106+
//!
107+
//! ```
108+
//! enum Kingdom { Plant(uint, &'static str), Animal(uint, &'static str) }
109+
//!
110+
//! // A list of data to search through.
111+
//! let all_the_big_things = [
112+
//! Plant(250, "redwood"),
113+
//! Plant(230, "noble fir"),
114+
//! Plant(229, "sugar pine"),
115+
//! Animal(25, "blue whale"),
116+
//! Animal(19, "fin whale"),
117+
//! Animal(15, "north pacific right whale"),
118+
//! ];
119+
//!
120+
//! // We're going to search for the name of the biggest animal,
121+
//! // but to start with we've just got `None`.
122+
//! let mut name_of_biggest_animal = None;
123+
//! let mut size_of_biggest_animal = 0;
124+
//! for big_thing in all_the_big_things.iter() {
125+
//! match *big_thing {
126+
//! Animal(size, name) if size > size_of_biggest_animal => {
127+
//! // Now we've found the name of some big animal
128+
//! size_of_biggest_animal = size;
129+
//! name_of_biggest_animal = Some(name);
130+
//! }
131+
//! Animal(..) | Plant(..) => ()
132+
//! }
133+
//! }
134+
//!
135+
//! match name_of_biggest_animal {
136+
//! Some(name) => println!("the biggest animal is {}", name),
137+
//! None => println!("there are no animals :(")
138+
//! }
139+
//! ```
140+
141+
use any::Any;
142+
use kinds::Send;
143+
144+
pub use core::option::{Option, Some, None, Item, collect};
145+
146+
/// Extension trait for the `Option` type to add an `expect` method
147+
148+
// FIXME(#14008) should this trait even exist?
149+
pub trait Expect<T> {
150+
/// Unwraps an option, yielding the content of a `Some`
151+
///
152+
/// # Failure
153+
///
154+
/// Fails if the value is a `None` with a custom failure message provided by
155+
/// `msg`.
156+
fn expect<M: Any + Send>(self, m: M) -> T;
157+
}
158+
159+
impl<T> Expect<T> for Option<T> {
160+
#[inline]
161+
fn expect<M: Any + Send>(self, msg: M) -> T {
162+
match self {
163+
Some(val) => val,
164+
None => fail!(msg),
165+
}
166+
}
167+
}

src/libstd/prelude.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize};
6565
pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul};
6666
pub use num::{Signed, Unsigned};
6767
pub use num::{Primitive, Int, Float, ToPrimitive, FromPrimitive};
68+
pub use option::Expect;
6869
pub use owned::Box;
6970
pub use path::{GenericPath, Path, PosixPath, WindowsPath};
7071
pub use ptr::RawPtr;

src/libstd/rt/env.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! Runtime environment settings
1212
1313
use from_str::from_str;
14-
use option::{Some, None};
14+
use option::{Some, None, Expect};
1515
use os;
1616

1717
// Note that these are all accessed without any synchronization.

src/libstd/vec.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use mem;
2323
use num;
2424
use num::{CheckedMul, CheckedAdd};
2525
use ops::Drop;
26-
use option::{None, Option, Some};
26+
use option::{None, Option, Some, Expect};
2727
use ptr::RawPtr;
2828
use ptr;
2929
use rt::global_heap::{malloc_raw, realloc_raw};

0 commit comments

Comments
 (0)