Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std: Fully stabilize Option<T> #19849

Merged
merged 1 commit into from
Dec 17, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 87 additions & 26 deletions src/libcore/option.rs
Original file line number Diff line number Diff line change
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]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just FYI, I don't believe the stability attributes on methods in trait impls have any meaning.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc #14407 for why that doesn't warn.

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> }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't Item the "proper" name for this iterator according to the naming conventions RFC?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't find the right RFC for it, if it exists, but this has always been @aturon's intention for the names to become.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While Item used to be the conventional name, we've since tweaked the conventions so the name of the iterator returned should match the name of the method of iteration.


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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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