Skip to content

Commit

Permalink
std: Fully stabilize Option<T>
Browse files Browse the repository at this point in the history
This commit takes a second pass through the `std::option` module to fully
stabilize any lingering methods inside of it.

These items were made stable as-is

* Some
* None
* as_mut
* expect
* unwrap
* unwrap_or
* unwrap_or_else
* map
* map_or
* map_or_else
* and_then
* or_else
* unwrap_or_default
* Default implementation
* FromIterator implementation
* Copy implementation

These items were made stable with modifications

* iter - now returns a struct called Iter
* iter_mut - now returns a struct called IterMut
* into_iter - now returns a struct called IntoIter, Clone is never implemented

This is a breaking change due to the modifications to the names of the iterator
types returned. Code referencing the old names should updated to referencing the
newer names instead. This is also a breaking change due to the fact that
`IntoIter` no longer implements the `Clone` trait.

These items were explicitly not stabilized

* as_slice - waiting on indexing conventions
* as_mut_slice - waiting on conventions with as_slice as well
* cloned - the API was still just recently added
* ok_or - API remains experimental
* ok_or_else - API remains experimental

[breaking-change]
  • Loading branch information
alexcrichton committed Dec 14, 2014
1 parent 444fa1b commit 1fbca88
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 32 deletions.
113 changes: 87 additions & 26 deletions src/libcore/option.rs
Expand Up @@ -168,8 +168,10 @@ use ops::{Deref, FnOnce};
#[stable]
pub enum Option<T> {
/// No value
#[stable]
None,
/// Some value `T`
#[stable]
Some(T)
}

Expand Down Expand Up @@ -261,7 +263,7 @@ impl<T> Option<T> {
/// assert_eq!(x, Some(42u));
/// ```
#[inline]
#[unstable = "waiting for mut conventions"]
#[stable]
pub fn as_mut<'r>(&'r mut self) -> Option<&'r mut T> {
match *self {
Some(ref mut x) => Some(x),
Expand Down Expand Up @@ -321,7 +323,7 @@ impl<T> Option<T> {
/// x.expect("the world is ending"); // panics with `world is ending`
/// ```
#[inline]
#[unstable = "waiting for conventions"]
#[stable]
pub fn expect(self, msg: &str) -> T {
match self {
Some(val) => val,
Expand Down Expand Up @@ -353,7 +355,7 @@ impl<T> Option<T> {
/// assert_eq!(x.unwrap(), "air"); // fails
/// ```
#[inline]
#[unstable = "waiting for conventions"]
#[stable]
pub fn unwrap(self) -> T {
match self {
Some(val) => val,
Expand All @@ -370,7 +372,7 @@ impl<T> Option<T> {
/// assert_eq!(None.unwrap_or("bike"), "bike");
/// ```
#[inline]
#[unstable = "waiting for conventions"]
#[stable]
pub fn unwrap_or(self, def: T) -> T {
match self {
Some(x) => x,
Expand All @@ -388,7 +390,7 @@ impl<T> Option<T> {
/// assert_eq!(None.unwrap_or_else(|| 2 * k), 20u);
/// ```
#[inline]
#[unstable = "waiting for conventions"]
#[stable]
pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
match self {
Some(x) => x,
Expand All @@ -412,7 +414,7 @@ impl<T> Option<T> {
/// let num_as_int: Option<uint> = num_as_str.map(|n| n.len());
/// ```
#[inline]
#[unstable = "waiting for unboxed closures"]
#[stable]
pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {
match self {
Some(x) => Some(f(x)),
Expand All @@ -432,7 +434,7 @@ impl<T> Option<T> {
/// assert_eq!(x.map_or(42u, |v| v.len()), 42u);
/// ```
#[inline]
#[unstable = "waiting for unboxed closures"]
#[stable]
pub fn map_or<U, F: FnOnce(T) -> U>(self, def: U, f: F) -> U {
match self {
Some(t) => f(t),
Expand All @@ -454,7 +456,7 @@ impl<T> Option<T> {
/// assert_eq!(x.map_or_else(|| 2 * k, |v| v.len()), 42u);
/// ```
#[inline]
#[unstable = "waiting for unboxed closures"]
#[stable]
pub fn map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, def: D, f: F) -> U {
match self {
Some(t) => f(t),
Expand Down Expand Up @@ -520,9 +522,9 @@ impl<T> Option<T> {
/// assert_eq!(x.iter().next(), None);
/// ```
#[inline]
#[unstable = "waiting for iterator conventions"]
pub fn iter<'r>(&'r self) -> Item<&'r T> {
Item{opt: self.as_ref()}
#[stable]
pub fn iter(&self) -> Iter<T> {
Iter { inner: Item { opt: self.as_ref() } }
}

/// Returns a mutable iterator over the possibly contained value.
Expand All @@ -542,8 +544,8 @@ impl<T> Option<T> {
/// ```
#[inline]
#[unstable = "waiting for iterator conventions"]
pub fn iter_mut<'r>(&'r mut self) -> Item<&'r mut T> {
Item{opt: self.as_mut()}
pub fn iter_mut(&mut self) -> IterMut<T> {
IterMut { inner: Item { opt: self.as_mut() } }
}

/// Returns a consuming iterator over the possibly contained value.
Expand All @@ -560,9 +562,9 @@ impl<T> Option<T> {
/// assert!(v.is_empty());
/// ```
#[inline]
#[unstable = "waiting for iterator conventions"]
pub fn into_iter(self) -> Item<T> {
Item{opt: self}
#[stable]
pub fn into_iter(self) -> IntoIter<T> {
IntoIter { inner: Item { opt: self } }
}

/////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -614,7 +616,7 @@ impl<T> Option<T> {
/// assert_eq!(None.and_then(sq).and_then(sq), None);
/// ```
#[inline]
#[unstable = "waiting for unboxed closures"]
#[stable]
pub fn and_then<U, F: FnOnce(T) -> Option<U>>(self, f: F) -> Option<U> {
match self {
Some(x) => f(x),
Expand Down Expand Up @@ -666,7 +668,7 @@ impl<T> Option<T> {
/// assert_eq!(None.or_else(nobody), None);
/// ```
#[inline]
#[unstable = "waiting for unboxed closures"]
#[stable]
pub fn or_else<F: FnOnce() -> Option<T>>(self, f: F) -> Option<T> {
match self {
Some(_) => self,
Expand Down Expand Up @@ -731,7 +733,7 @@ impl<T: Default> Option<T> {
/// assert_eq!(0i, bad_year);
/// ```
#[inline]
#[unstable = "waiting for conventions"]
#[stable]
pub fn unwrap_or_default(self) -> T {
match self {
Some(x) => x,
Expand All @@ -744,6 +746,7 @@ impl<T: Default> Option<T> {
// Trait implementations
/////////////////////////////////////////////////////////////////////////////

#[unstable = "waiting on the stability of the trait itself"]
impl<T> AsSlice<T> for Option<T> {
/// Convert from `Option<T>` to `&[T]` (without copying)
#[inline]
Expand All @@ -761,20 +764,16 @@ impl<T> AsSlice<T> for Option<T> {
#[stable]
impl<T> Default for Option<T> {
#[inline]
#[stable]
fn default() -> Option<T> { None }
}

/////////////////////////////////////////////////////////////////////////////
// The Option Iterator
// The Option Iterators
/////////////////////////////////////////////////////////////////////////////

/// An `Option` iterator that yields either one or zero elements
///
/// The `Item` iterator is returned by the `iter`, `iter_mut` and `into_iter`
/// methods on `Option`.
#[deriving(Clone)]
#[unstable = "waiting for iterator conventions"]
pub struct Item<A> {
struct Item<A> {
opt: Option<A>
}

Expand Down Expand Up @@ -802,6 +801,66 @@ impl<A> DoubleEndedIterator<A> for Item<A> {

impl<A> ExactSizeIterator<A> for Item<A> {}

/// An iterator over a reference of the contained item in an Option.
#[stable]
pub struct Iter<'a, A: 'a> { inner: Item<&'a A> }

impl<'a, A> Iterator<&'a A> for Iter<'a, A> {
#[inline]
fn next(&mut self) -> Option<&'a A> { self.inner.next() }
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
}

impl<'a, A> DoubleEndedIterator<&'a A> for Iter<'a, A> {
#[inline]
fn next_back(&mut self) -> Option<&'a A> { self.inner.next_back() }
}

impl<'a, A> ExactSizeIterator<&'a A> for Iter<'a, A> {}

impl<'a, A> Clone for Iter<'a, A> {
fn clone(&self) -> Iter<'a, A> {
Iter { inner: self.inner.clone() }
}
}

/// An iterator over a mutable reference of the contained item in an Option.
#[stable]
pub struct IterMut<'a, A: 'a> { inner: Item<&'a mut A> }

impl<'a, A> Iterator<&'a mut A> for IterMut<'a, A> {
#[inline]
fn next(&mut self) -> Option<&'a mut A> { self.inner.next() }
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
}

impl<'a, A> DoubleEndedIterator<&'a mut A> for IterMut<'a, A> {
#[inline]
fn next_back(&mut self) -> Option<&'a mut A> { self.inner.next_back() }
}

impl<'a, A> ExactSizeIterator<&'a mut A> for IterMut<'a, A> {}

/// An iterator over the item contained inside an Option.
#[stable]
pub struct IntoIter<A> { inner: Item<A> }

impl<A> Iterator<A> for IntoIter<A> {
#[inline]
fn next(&mut self) -> Option<A> { self.inner.next() }
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
}

impl<A> DoubleEndedIterator<A> for IntoIter<A> {
#[inline]
fn next_back(&mut self) -> Option<A> { self.inner.next_back() }
}

impl<A> ExactSizeIterator<A> for IntoIter<A> {}

/////////////////////////////////////////////////////////////////////////////
// FromIterator
/////////////////////////////////////////////////////////////////////////////
Expand All @@ -826,6 +885,7 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
/// assert!(res == Some(vec!(2u, 3u)));
/// ```
#[inline]
#[stable]
fn from_iter<I: Iterator<Option<A>>>(iter: I) -> Option<V> {
// FIXME(#11084): This could be replaced with Iterator::scan when this
// performance bug is closed.
Expand Down Expand Up @@ -860,5 +920,6 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
}
}

#[stable]
impl<T:Copy> Copy for Option<T> {}

10 changes: 5 additions & 5 deletions src/librustc/metadata/encoder.rs
Expand Up @@ -364,12 +364,12 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
}
}

fn encode_path<PI: Iterator<PathElem> + Clone>(rbml_w: &mut Encoder,
mut path: PI) {
fn encode_path<PI: Iterator<PathElem>>(rbml_w: &mut Encoder, path: PI) {
let path = path.collect::<Vec<_>>();
rbml_w.start_tag(tag_path);
rbml_w.wr_tagged_u32(tag_path_len, path.clone().count() as u32);
for pe in path {
let tag = match pe {
rbml_w.wr_tagged_u32(tag_path_len, path.len() as u32);
for pe in path.iter() {
let tag = match *pe {
ast_map::PathMod(_) => tag_path_elem_mod,
ast_map::PathName(_) => tag_path_elem_name
};
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_driver/pretty.rs
Expand Up @@ -325,7 +325,7 @@ impl FromStr for UserIdentifiedItem {
}

enum NodesMatchingUII<'a, 'ast: 'a> {
NodesMatchingDirect(option::Item<ast::NodeId>),
NodesMatchingDirect(option::IntoIter<ast::NodeId>),
NodesMatchingSuffix(ast_map::NodesMatchingSuffix<'a, 'ast, String>),
}

Expand Down

0 comments on commit 1fbca88

Please sign in to comment.