From 1fbca8824a6b6018191b7ee998d2c97f30c481d7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 14 Dec 2014 10:34:23 -0800 Subject: [PATCH] std: Fully stabilize Option 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] --- src/libcore/option.rs | 113 ++++++++++++++++++++++++------- src/librustc/metadata/encoder.rs | 10 +-- src/librustc_driver/pretty.rs | 2 +- 3 files changed, 93 insertions(+), 32 deletions(-) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 7be47f73e9ee7..58d71e0ed0889 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -168,8 +168,10 @@ use ops::{Deref, FnOnce}; #[stable] pub enum Option { /// No value + #[stable] None, /// Some value `T` + #[stable] Some(T) } @@ -261,7 +263,7 @@ impl Option { /// 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), @@ -321,7 +323,7 @@ impl Option { /// 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, @@ -353,7 +355,7 @@ impl Option { /// assert_eq!(x.unwrap(), "air"); // fails /// ``` #[inline] - #[unstable = "waiting for conventions"] + #[stable] pub fn unwrap(self) -> T { match self { Some(val) => val, @@ -370,7 +372,7 @@ impl Option { /// 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, @@ -388,7 +390,7 @@ impl Option { /// assert_eq!(None.unwrap_or_else(|| 2 * k), 20u); /// ``` #[inline] - #[unstable = "waiting for conventions"] + #[stable] pub fn unwrap_or_else T>(self, f: F) -> T { match self { Some(x) => x, @@ -412,7 +414,7 @@ impl Option { /// let num_as_int: Option = num_as_str.map(|n| n.len()); /// ``` #[inline] - #[unstable = "waiting for unboxed closures"] + #[stable] pub fn map U>(self, f: F) -> Option { match self { Some(x) => Some(f(x)), @@ -432,7 +434,7 @@ impl Option { /// assert_eq!(x.map_or(42u, |v| v.len()), 42u); /// ``` #[inline] - #[unstable = "waiting for unboxed closures"] + #[stable] pub fn map_or U>(self, def: U, f: F) -> U { match self { Some(t) => f(t), @@ -454,7 +456,7 @@ impl Option { /// 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, F: FnOnce(T) -> U>(self, def: D, f: F) -> U { match self { Some(t) => f(t), @@ -520,9 +522,9 @@ impl Option { /// 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 { + Iter { inner: Item { opt: self.as_ref() } } } /// Returns a mutable iterator over the possibly contained value. @@ -542,8 +544,8 @@ impl Option { /// ``` #[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 { + IterMut { inner: Item { opt: self.as_mut() } } } /// Returns a consuming iterator over the possibly contained value. @@ -560,9 +562,9 @@ impl Option { /// assert!(v.is_empty()); /// ``` #[inline] - #[unstable = "waiting for iterator conventions"] - pub fn into_iter(self) -> Item { - Item{opt: self} + #[stable] + pub fn into_iter(self) -> IntoIter { + IntoIter { inner: Item { opt: self } } } ///////////////////////////////////////////////////////////////////////// @@ -614,7 +616,7 @@ impl Option { /// assert_eq!(None.and_then(sq).and_then(sq), None); /// ``` #[inline] - #[unstable = "waiting for unboxed closures"] + #[stable] pub fn and_then Option>(self, f: F) -> Option { match self { Some(x) => f(x), @@ -666,7 +668,7 @@ impl Option { /// assert_eq!(None.or_else(nobody), None); /// ``` #[inline] - #[unstable = "waiting for unboxed closures"] + #[stable] pub fn or_else Option>(self, f: F) -> Option { match self { Some(_) => self, @@ -731,7 +733,7 @@ impl Option { /// assert_eq!(0i, bad_year); /// ``` #[inline] - #[unstable = "waiting for conventions"] + #[stable] pub fn unwrap_or_default(self) -> T { match self { Some(x) => x, @@ -744,6 +746,7 @@ impl Option { // Trait implementations ///////////////////////////////////////////////////////////////////////////// +#[unstable = "waiting on the stability of the trait itself"] impl AsSlice for Option { /// Convert from `Option` to `&[T]` (without copying) #[inline] @@ -761,20 +764,16 @@ impl AsSlice for Option { #[stable] impl Default for Option { #[inline] + #[stable] fn default() -> Option { 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 { +struct Item { opt: Option } @@ -802,6 +801,66 @@ impl DoubleEndedIterator for Item { impl ExactSizeIterator for Item {} +/// 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) { 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) { 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 { inner: Item } + +impl Iterator for IntoIter { + #[inline] + fn next(&mut self) -> Option { self.inner.next() } + #[inline] + fn size_hint(&self) -> (uint, Option) { self.inner.size_hint() } +} + +impl DoubleEndedIterator for IntoIter { + #[inline] + fn next_back(&mut self) -> Option { self.inner.next_back() } +} + +impl ExactSizeIterator for IntoIter {} + ///////////////////////////////////////////////////////////////////////////// // FromIterator ///////////////////////////////////////////////////////////////////////////// @@ -826,6 +885,7 @@ impl> FromIterator> for Option { /// assert!(res == Some(vec!(2u, 3u))); /// ``` #[inline] + #[stable] fn from_iter>>(iter: I) -> Option { // FIXME(#11084): This could be replaced with Iterator::scan when this // performance bug is closed. @@ -860,5 +920,6 @@ impl> FromIterator> for Option { } } +#[stable] impl Copy for Option {} diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 9804e3c20aa35..9381c97d49dca 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -364,12 +364,12 @@ fn encode_enum_variant_info(ecx: &EncodeContext, } } -fn encode_path + Clone>(rbml_w: &mut Encoder, - mut path: PI) { +fn encode_path>(rbml_w: &mut Encoder, path: PI) { + let path = path.collect::>(); 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 }; diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 7ec05b6a0306e..57004d71c75e4 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -325,7 +325,7 @@ impl FromStr for UserIdentifiedItem { } enum NodesMatchingUII<'a, 'ast: 'a> { - NodesMatchingDirect(option::Item), + NodesMatchingDirect(option::IntoIter), NodesMatchingSuffix(ast_map::NodesMatchingSuffix<'a, 'ast, String>), }