about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-12-18 17:37:25 +0000
committerbors <bors@rust-lang.org>2016-12-18 17:37:25 +0000
commit1f965cc8e9dc8f8b26eac99cffdef6501cf0c617 (patch)
treee0df29c8bc2f181da612f1685364c0eee24a15e1
parent8327b5afafde7cdd6fd4e939d9a8fe12f76503ef (diff)
parent9a5cef4de51c1c90fb2d05b0c7e6feb9cf0224d6 (diff)
downloadrust-1f965cc8e9dc8f8b26eac99cffdef6501cf0c617.tar.gz
rust-1f965cc8e9dc8f8b26eac99cffdef6501cf0c617.zip
Auto merge of #38369 - aturon:stab-1.15, r=alexcrichton
Library stabilizations/deprecations for 1.15 release

Stabilized:

- `std::iter::Iterator::{min_by, max_by}`
- `std::os::*::fs::FileExt`
- `std::sync::atomic::Atomic*::{get_mut, into_inner}`
- `std::vec::IntoIter::{as_slice, as_mut_slice}`
- `std::sync::mpsc::Receiver::try_iter`
- `std::os::unix::process::CommandExt::before_exec`
- `std::rc::Rc::{strong_count, weak_count}`
- `std::sync::Arc::{strong_count, weak_count}`
- `std::char::{encode_utf8, encode_utf16}`
- `std::cell::Ref::clone`
- `std::io::Take::into_inner`

Deprecated:

- `std::rc::Rc::{would_unwrap, is_unique}`
- `std::cell::RefCell::borrow_state`

Closes #23755
Closes #27733
Closes #27746
Closes #27784
Closes #28356
Closes #31398
Closes #34931
Closes #35601
Closes #35603
Closes #35918
Closes #36105
-rw-r--r--src/liballoc/arc.rs10
-rw-r--r--src/liballoc/rc.rs46
-rw-r--r--src/libcollections/vec.rs6
-rw-r--r--src/libcollectionstest/lib.rs1
-rw-r--r--src/libcore/cell.rs8
-rw-r--r--src/libcore/char.rs4
-rw-r--r--src/libcore/fmt/mod.rs10
-rw-r--r--src/libcore/iter/iterator.rs6
-rw-r--r--src/libcore/sync/atomic.rs18
-rw-r--r--src/libcoretest/cell.rs37
-rw-r--r--src/libcoretest/lib.rs4
-rw-r--r--src/librustc/dep_graph/shadow.rs16
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc_resolve/lib.rs1
-rw-r--r--src/librustc_resolve/resolve_imports.rs8
-rw-r--r--src/librustc_trans/lib.rs1
-rw-r--r--src/libstd/io/mod.rs4
-rw-r--r--src/libstd/io/stdio.rs6
-rw-r--r--src/libstd/sync/mpsc/mod.rs6
-rw-r--r--src/libstd/sys/redox/ext/process.rs2
-rw-r--r--src/libstd/sys/unix/ext/fs.rs8
-rw-r--r--src/libstd/sys/unix/ext/mod.rs2
-rw-r--r--src/libstd/sys/unix/ext/process.rs2
-rw-r--r--src/libstd/sys/windows/ext/fs.rs8
-rw-r--r--src/libstd/sys/windows/ext/mod.rs2
-rw-r--r--src/libstd_unicode/char.rs14
-rw-r--r--src/libstd_unicode/lib.rs1
27 files changed, 83 insertions, 149 deletions
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 3a7da18c8de..1cad8f7f407 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -392,8 +392,6 @@ impl<T: ?Sized> Arc<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(arc_counts)]
-    ///
     /// use std::sync::Arc;
     ///
     /// let five = Arc::new(5);
@@ -404,8 +402,7 @@ impl<T: ?Sized> Arc<T> {
     /// assert_eq!(1, Arc::weak_count(&five));
     /// ```
     #[inline]
-    #[unstable(feature = "arc_counts", reason = "not clearly useful, and racy",
-               issue = "28356")]
+    #[stable(feature = "arc_counts", since = "1.15.0")]
     pub fn weak_count(this: &Self) -> usize {
         this.inner().weak.load(SeqCst) - 1
     }
@@ -421,8 +418,6 @@ impl<T: ?Sized> Arc<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(arc_counts)]
-    ///
     /// use std::sync::Arc;
     ///
     /// let five = Arc::new(5);
@@ -433,8 +428,7 @@ impl<T: ?Sized> Arc<T> {
     /// assert_eq!(2, Arc::strong_count(&five));
     /// ```
     #[inline]
-    #[unstable(feature = "arc_counts", reason = "not clearly useful, and racy",
-               issue = "28356")]
+    #[stable(feature = "arc_counts", since = "1.15.0")]
     pub fn strong_count(this: &Self) -> usize {
         this.inner().strong.load(SeqCst)
     }
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index d1e0e333b8f..86f8c746646 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -320,7 +320,7 @@ impl<T> Rc<T> {
     #[inline]
     #[stable(feature = "rc_unique", since = "1.4.0")]
     pub fn try_unwrap(this: Self) -> Result<T, Self> {
-        if Rc::would_unwrap(&this) {
+        if Rc::strong_count(&this) == 1 {
             unsafe {
                 let val = ptr::read(&*this); // copy the contained object
 
@@ -343,26 +343,10 @@ impl<T> Rc<T> {
     ///
     /// [try_unwrap]: struct.Rc.html#method.try_unwrap
     /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(rc_would_unwrap)]
-    ///
-    /// use std::rc::Rc;
-    ///
-    /// let x = Rc::new(3);
-    /// assert!(Rc::would_unwrap(&x));
-    /// assert_eq!(Rc::try_unwrap(x), Ok(3));
-    ///
-    /// let x = Rc::new(4);
-    /// let _y = x.clone();
-    /// assert!(!Rc::would_unwrap(&x));
-    /// assert_eq!(*Rc::try_unwrap(x).unwrap_err(), 4);
-    /// ```
     #[unstable(feature = "rc_would_unwrap",
                reason = "just added for niche usecase",
                issue = "28356")]
+    #[rustc_deprecated(since = "1.15.0", reason = "too niche; use `strong_count` instead")]
     pub fn would_unwrap(this: &Self) -> bool {
         Rc::strong_count(&this) == 1
     }
@@ -482,8 +466,6 @@ impl<T: ?Sized> Rc<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(rc_counts)]
-    ///
     /// use std::rc::Rc;
     ///
     /// let five = Rc::new(5);
@@ -492,8 +474,7 @@ impl<T: ?Sized> Rc<T> {
     /// assert_eq!(1, Rc::weak_count(&five));
     /// ```
     #[inline]
-    #[unstable(feature = "rc_counts", reason = "not clearly useful",
-               issue = "28356")]
+    #[stable(feature = "rc_counts", since = "1.15.0")]
     pub fn weak_count(this: &Self) -> usize {
         this.weak() - 1
     }
@@ -503,8 +484,6 @@ impl<T: ?Sized> Rc<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(rc_counts)]
-    ///
     /// use std::rc::Rc;
     ///
     /// let five = Rc::new(5);
@@ -513,8 +492,7 @@ impl<T: ?Sized> Rc<T> {
     /// assert_eq!(2, Rc::strong_count(&five));
     /// ```
     #[inline]
-    #[unstable(feature = "rc_counts", reason = "not clearly useful",
-               issue = "28356")]
+    #[stable(feature = "rc_counts", since = "1.15.0")]
     pub fn strong_count(this: &Self) -> usize {
         this.strong()
     }
@@ -523,21 +501,11 @@ impl<T: ?Sized> Rc<T> {
     /// this inner value.
     ///
     /// [weak]: struct.Weak.html
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(rc_counts)]
-    ///
-    /// use std::rc::Rc;
-    ///
-    /// let five = Rc::new(5);
-    ///
-    /// assert!(Rc::is_unique(&five));
-    /// ```
     #[inline]
-    #[unstable(feature = "rc_counts", reason = "uniqueness has unclear meaning",
+    #[unstable(feature = "is_unique", reason = "uniqueness has unclear meaning",
                issue = "28356")]
+    #[rustc_deprecated(since = "1.15.0",
+                       reason = "too niche; use `strong_count` and `weak_count` instead")]
     pub fn is_unique(this: &Self) -> bool {
         Rc::weak_count(this) == 0 && Rc::strong_count(this) == 1
     }
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index c9f9e513ef3..f2ef54f6e56 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -1902,14 +1902,13 @@ impl<T> IntoIter<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vec_into_iter_as_slice)]
     /// let vec = vec!['a', 'b', 'c'];
     /// let mut into_iter = vec.into_iter();
     /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
     /// let _ = into_iter.next().unwrap();
     /// assert_eq!(into_iter.as_slice(), &['b', 'c']);
     /// ```
-    #[unstable(feature = "vec_into_iter_as_slice", issue = "35601")]
+    #[stable(feature = "vec_into_iter_as_slice", since = "1.15.0")]
     pub fn as_slice(&self) -> &[T] {
         unsafe {
             slice::from_raw_parts(self.ptr, self.len())
@@ -1921,7 +1920,6 @@ impl<T> IntoIter<T> {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(vec_into_iter_as_slice)]
     /// let vec = vec!['a', 'b', 'c'];
     /// let mut into_iter = vec.into_iter();
     /// assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
@@ -1930,7 +1928,7 @@ impl<T> IntoIter<T> {
     /// assert_eq!(into_iter.next().unwrap(), 'b');
     /// assert_eq!(into_iter.next().unwrap(), 'z');
     /// ```
-    #[unstable(feature = "vec_into_iter_as_slice", issue = "35601")]
+    #[stable(feature = "vec_into_iter_as_slice", since = "1.15.0")]
     pub fn as_mut_slice(&self) -> &mut [T] {
         unsafe {
             slice::from_raw_parts_mut(self.ptr as *mut T, self.len())
diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs
index 0fe0a1bad64..d4fb5ea03ad 100644
--- a/src/libcollectionstest/lib.rs
+++ b/src/libcollectionstest/lib.rs
@@ -29,7 +29,6 @@
 #![feature(test)]
 #![feature(unboxed_closures)]
 #![feature(unicode)]
-#![feature(vec_into_iter_as_slice)]
 
 extern crate collections;
 extern crate test;
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index 64a7a8c5ef7..c3f862e7c54 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -393,6 +393,8 @@ pub struct RefCell<T: ?Sized> {
 /// An enumeration of values returned from the `state` method on a `RefCell<T>`.
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 #[unstable(feature = "borrow_state", issue = "27733")]
+#[rustc_deprecated(since = "1.15.0", reason = "use `try_borrow` instead")]
+#[allow(deprecated)]
 pub enum BorrowState {
     /// The cell is currently being read, there is at least one active `borrow`.
     Reading,
@@ -511,6 +513,8 @@ impl<T: ?Sized> RefCell<T> {
     /// }
     /// ```
     #[unstable(feature = "borrow_state", issue = "27733")]
+    #[rustc_deprecated(since = "1.15.0", reason = "use `try_borrow` instead")]
+    #[allow(deprecated)]
     #[inline]
     pub fn borrow_state(&self) -> BorrowState {
         match self.borrow.get() {
@@ -888,9 +892,7 @@ impl<'b, T: ?Sized> Ref<'b, T> {
     /// `Ref::clone(...)`.  A `Clone` implementation or a method would interfere
     /// with the widespread use of `r.borrow().clone()` to clone the contents of
     /// a `RefCell`.
-    #[unstable(feature = "cell_extras",
-               reason = "likely to be moved to a method, pending language changes",
-               issue = "27746")]
+    #[stable(feature = "cell_extras", since = "1.15.0")]
     #[inline]
     pub fn clone(orig: &Ref<'b, T>) -> Ref<'b, T> {
         Ref {
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index 7f3ac13bac1..c14ae6e0898 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -327,9 +327,9 @@ pub trait CharExt {
     fn len_utf8(self) -> usize;
     #[stable(feature = "core", since = "1.6.0")]
     fn len_utf16(self) -> usize;
-    #[unstable(feature = "unicode", issue = "27784")]
+    #[stable(feature = "unicode_encode_char", since = "1.15.0")]
     fn encode_utf8(self, dst: &mut [u8]) -> &mut str;
-    #[unstable(feature = "unicode", issue = "27784")]
+    #[stable(feature = "unicode_encode_char", since = "1.15.0")]
     fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16];
 }
 
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 9167264ba9d..2ba7d6e8bd1 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -12,7 +12,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use cell::{UnsafeCell, Cell, RefCell, Ref, RefMut, BorrowState};
+use cell::{UnsafeCell, Cell, RefCell, Ref, RefMut};
 use marker::PhantomData;
 use mem;
 use num::flt2dec;
@@ -1634,13 +1634,13 @@ impl<T: Copy + Debug> Debug for Cell<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + Debug> Debug for RefCell<T> {
     fn fmt(&self, f: &mut Formatter) -> Result {
-        match self.borrow_state() {
-            BorrowState::Unused | BorrowState::Reading => {
+        match self.try_borrow() {
+            Ok(borrow) => {
                 f.debug_struct("RefCell")
-                    .field("value", &self.borrow())
+                    .field("value", &borrow)
                     .finish()
             }
-            BorrowState::Writing => {
+            Err(_) => {
                 f.debug_struct("RefCell")
                     .field("value", &"<borrowed>")
                     .finish()
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index 48808b601c1..ec590d2bd06 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -1696,12 +1696,11 @@ pub trait Iterator {
     /// # Examples
     ///
     /// ```
-    /// #![feature(iter_max_by)]
     /// let a = [-3_i32, 0, 1, 5, -10];
     /// assert_eq!(*a.iter().max_by(|x, y| x.cmp(y)).unwrap(), 5);
     /// ```
     #[inline]
-    #[unstable(feature = "iter_max_by", issue="36105")]
+    #[stable(feature = "iter_max_by", since = "1.15.0")]
     fn max_by<F>(self, mut compare: F) -> Option<Self::Item>
         where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,
     {
@@ -1746,12 +1745,11 @@ pub trait Iterator {
     /// # Examples
     ///
     /// ```
-    /// #![feature(iter_min_by)]
     /// let a = [-3_i32, 0, 1, 5, -10];
     /// assert_eq!(*a.iter().min_by(|x, y| x.cmp(y)).unwrap(), -10);
     /// ```
     #[inline]
-    #[unstable(feature = "iter_min_by", issue="36105")]
+    #[stable(feature = "iter_min_by", since = "1.15.0")]
     fn min_by<F>(self, mut compare: F) -> Option<Self::Item>
         where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,
     {
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index c10f7e39fc3..198db0e7c0a 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -203,7 +203,6 @@ impl AtomicBool {
     /// # Examples
     ///
     /// ```
-    /// #![feature(atomic_access)]
     /// use std::sync::atomic::{AtomicBool, Ordering};
     ///
     /// let mut some_bool = AtomicBool::new(true);
@@ -212,7 +211,7 @@ impl AtomicBool {
     /// assert_eq!(some_bool.load(Ordering::SeqCst), false);
     /// ```
     #[inline]
-    #[unstable(feature = "atomic_access", issue = "35603")]
+    #[stable(feature = "atomic_access", since = "1.15.0")]
     pub fn get_mut(&mut self) -> &mut bool {
         unsafe { &mut *(self.v.get() as *mut bool) }
     }
@@ -225,14 +224,13 @@ impl AtomicBool {
     /// # Examples
     ///
     /// ```
-    /// #![feature(atomic_access)]
     /// use std::sync::atomic::AtomicBool;
     ///
     /// let some_bool = AtomicBool::new(true);
     /// assert_eq!(some_bool.into_inner(), true);
     /// ```
     #[inline]
-    #[unstable(feature = "atomic_access", issue = "35603")]
+    #[stable(feature = "atomic_access", since = "1.15.0")]
     pub fn into_inner(self) -> bool {
         unsafe { self.v.into_inner() != 0 }
     }
@@ -588,7 +586,6 @@ impl<T> AtomicPtr<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(atomic_access)]
     /// use std::sync::atomic::{AtomicPtr, Ordering};
     ///
     /// let mut atomic_ptr = AtomicPtr::new(&mut 10);
@@ -596,7 +593,7 @@ impl<T> AtomicPtr<T> {
     /// assert_eq!(unsafe { *atomic_ptr.load(Ordering::SeqCst) }, 5);
     /// ```
     #[inline]
-    #[unstable(feature = "atomic_access", issue = "35603")]
+    #[stable(feature = "atomic_access", since = "1.15.0")]
     pub fn get_mut(&mut self) -> &mut *mut T {
         unsafe { &mut *self.p.get() }
     }
@@ -609,14 +606,13 @@ impl<T> AtomicPtr<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(atomic_access)]
     /// use std::sync::atomic::AtomicPtr;
     ///
     /// let atomic_ptr = AtomicPtr::new(&mut 5);
     /// assert_eq!(unsafe { *atomic_ptr.into_inner() }, 5);
     /// ```
     #[inline]
-    #[unstable(feature = "atomic_access", issue = "35603")]
+    #[stable(feature = "atomic_access", since = "1.15.0")]
     pub fn into_inner(self) -> *mut T {
         unsafe { self.p.into_inner() }
     }
@@ -883,7 +879,6 @@ macro_rules! atomic_int {
             /// # Examples
             ///
             /// ```
-            /// #![feature(atomic_access)]
             /// use std::sync::atomic::{AtomicIsize, Ordering};
             ///
             /// let mut some_isize = AtomicIsize::new(10);
@@ -905,7 +900,6 @@ macro_rules! atomic_int {
             /// # Examples
             ///
             /// ```
-            /// #![feature(atomic_access)]
             /// use std::sync::atomic::AtomicIsize;
             ///
             /// let some_isize = AtomicIsize::new(5);
@@ -1261,7 +1255,7 @@ atomic_int!{
     stable(feature = "rust1", since = "1.0.0"),
     stable(feature = "extended_compare_and_swap", since = "1.10.0"),
     stable(feature = "atomic_debug", since = "1.3.0"),
-    unstable(feature = "atomic_access", issue = "35603"),
+    stable(feature = "atomic_access", since = "1.15.0"),
     isize AtomicIsize ATOMIC_ISIZE_INIT
 }
 #[cfg(target_has_atomic = "ptr")]
@@ -1269,7 +1263,7 @@ atomic_int!{
     stable(feature = "rust1", since = "1.0.0"),
     stable(feature = "extended_compare_and_swap", since = "1.10.0"),
     stable(feature = "atomic_debug", since = "1.3.0"),
-    unstable(feature = "atomic_access", issue = "35603"),
+    stable(feature = "atomic_access", since = "1.15.0"),
     usize AtomicUsize ATOMIC_USIZE_INIT
 }
 
diff --git a/src/libcoretest/cell.rs b/src/libcoretest/cell.rs
index a7c230ba979..724a312ea79 100644
--- a/src/libcoretest/cell.rs
+++ b/src/libcoretest/cell.rs
@@ -59,22 +59,22 @@ fn double_imm_borrow() {
 fn no_mut_then_imm_borrow() {
     let x = RefCell::new(0);
     let _b1 = x.borrow_mut();
-    assert_eq!(x.borrow_state(), BorrowState::Writing);
+    assert!(x.try_borrow().is_err());
 }
 
 #[test]
 fn no_imm_then_borrow_mut() {
     let x = RefCell::new(0);
     let _b1 = x.borrow();
-    assert_eq!(x.borrow_state(), BorrowState::Reading);
+    assert!(x.try_borrow_mut().is_err());
 }
 
 #[test]
 fn no_double_borrow_mut() {
     let x = RefCell::new(0);
-    assert_eq!(x.borrow_state(), BorrowState::Unused);
+    assert!(x.try_borrow().is_ok());
     let _b1 = x.borrow_mut();
-    assert_eq!(x.borrow_state(), BorrowState::Writing);
+    assert!(x.try_borrow().is_err());
 }
 
 #[test]
@@ -102,7 +102,8 @@ fn double_borrow_single_release_no_borrow_mut() {
     {
         let _b2 = x.borrow();
     }
-    assert_eq!(x.borrow_state(), BorrowState::Reading);
+    assert!(x.try_borrow().is_ok());
+    assert!(x.try_borrow_mut().is_err());
 }
 
 #[test]
@@ -119,14 +120,18 @@ fn ref_clone_updates_flag() {
     let x = RefCell::new(0);
     {
         let b1 = x.borrow();
-        assert_eq!(x.borrow_state(), BorrowState::Reading);
+        assert!(x.try_borrow().is_ok());
+        assert!(x.try_borrow_mut().is_err());
         {
             let _b2 = Ref::clone(&b1);
-            assert_eq!(x.borrow_state(), BorrowState::Reading);
+            assert!(x.try_borrow().is_ok());
+            assert!(x.try_borrow_mut().is_err());
         }
-        assert_eq!(x.borrow_state(), BorrowState::Reading);
+        assert!(x.try_borrow().is_ok());
+        assert!(x.try_borrow_mut().is_err());
     }
-    assert_eq!(x.borrow_state(), BorrowState::Unused);
+    assert!(x.try_borrow().is_ok());
+    assert!(x.try_borrow_mut().is_ok());
 }
 
 #[test]
@@ -134,15 +139,19 @@ fn ref_map_does_not_update_flag() {
     let x = RefCell::new(Some(5));
     {
         let b1: Ref<Option<u32>> = x.borrow();
-        assert_eq!(x.borrow_state(), BorrowState::Reading);
+        assert!(x.try_borrow().is_ok());
+        assert!(x.try_borrow_mut().is_err());
         {
             let b2: Ref<u32> = Ref::map(b1, |o| o.as_ref().unwrap());
             assert_eq!(*b2, 5);
-            assert_eq!(x.borrow_state(), BorrowState::Reading);
+            assert!(x.try_borrow().is_ok());
+            assert!(x.try_borrow_mut().is_err());
         }
-        assert_eq!(x.borrow_state(), BorrowState::Unused);
+        assert!(x.try_borrow().is_ok());
+        assert!(x.try_borrow_mut().is_ok());
     }
-    assert_eq!(x.borrow_state(), BorrowState::Unused);
+    assert!(x.try_borrow().is_ok());
+    assert!(x.try_borrow_mut().is_ok());
 }
 
 #[test]
@@ -247,5 +256,3 @@ fn refcell_ref_coercion() {
         assert_eq!(&*coerced, comp);
     }
 }
-
-
diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs
index 05d98d4a212..d12616a97a6 100644
--- a/src/libcoretest/lib.rs
+++ b/src/libcoretest/lib.rs
@@ -10,9 +10,7 @@
 
 #![deny(warnings)]
 
-#![feature(borrow_state)]
 #![feature(box_syntax)]
-#![feature(cell_extras)]
 #![feature(char_escape_debug)]
 #![feature(const_fn)]
 #![feature(core_private_bignum)]
@@ -32,8 +30,6 @@
 #![feature(try_from)]
 #![feature(unicode)]
 #![feature(unique)]
-#![feature(iter_max_by)]
-#![feature(iter_min_by)]
 #![feature(ordering_chaining)]
 #![feature(result_unwrap_or_default)]
 #![feature(ptr_unaligned)]
diff --git a/src/librustc/dep_graph/shadow.rs b/src/librustc/dep_graph/shadow.rs
index 06def4bf19a..5d4190a8ae1 100644
--- a/src/librustc/dep_graph/shadow.rs
+++ b/src/librustc/dep_graph/shadow.rs
@@ -27,7 +27,7 @@
 //! created.  See `./README.md` for details.
 
 use hir::def_id::DefId;
-use std::cell::{BorrowState, RefCell};
+use std::cell::RefCell;
 use std::env;
 
 use super::DepNode;
@@ -71,15 +71,11 @@ impl ShadowGraph {
 
     pub fn enqueue(&self, message: &DepMessage) {
         if ENABLED {
-            match self.stack.borrow_state() {
-                BorrowState::Unused => {}
-                _ => {
-                    // When we apply edge filters, that invokes the
-                    // Debug trait on DefIds, which in turn reads from
-                    // various bits of state and creates reads! Ignore
-                    // those recursive reads.
-                    return;
-                }
+            if self.stack.try_borrow().is_err() {
+                // When we apply edge filters, that invokes the Debug trait on
+                // DefIds, which in turn reads from various bits of state and
+                // creates reads! Ignore those recursive reads.
+                return;
             }
 
             let mut stack = self.stack.borrow_mut();
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 7c26b710a53..17cc34fcd83 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -24,7 +24,6 @@
 #![cfg_attr(not(stage0), deny(warnings))]
 
 #![feature(associated_consts)]
-#![feature(borrow_state)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(collections)]
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index ea5aa5be013..509ee704e2e 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -18,7 +18,6 @@
 #![cfg_attr(not(stage0), deny(warnings))]
 
 #![feature(associated_consts)]
-#![feature(borrow_state)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index b634d57a842..890891fd090 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -144,11 +144,9 @@ impl<'a> Resolver<'a> {
                                   -> Result<&'a NameBinding<'a>, Determinacy> {
         self.populate_module_if_necessary(module);
 
-        let resolution = self.resolution(module, name, ns);
-        let resolution = match resolution.borrow_state() {
-            ::std::cell::BorrowState::Unused => resolution.borrow_mut(),
-            _ => return Err(Determined), // This happens when there is a cycle of imports
-        };
+        let resolution = self.resolution(module, name, ns)
+            .try_borrow_mut()
+            .map_err(|_| Determined)?; // This happens when there is a cycle of imports
 
         if let Some(span) = record_used {
             if let Some(binding) = resolution.binding {
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index e2da635b159..d842827b6fe 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -26,7 +26,6 @@
 #![feature(associated_consts)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
-#![feature(cell_extras)]
 #![feature(const_fn)]
 #![feature(custom_attribute)]
 #![allow(unused_attributes)]
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index b3b89213df1..b07da0dc268 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -1526,8 +1526,6 @@ impl<T> Take<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(io_take_into_inner)]
-    ///
     /// use std::io;
     /// use std::io::prelude::*;
     /// use std::fs::File;
@@ -1543,7 +1541,7 @@ impl<T> Take<T> {
     /// # Ok(())
     /// # }
     /// ```
-    #[unstable(feature = "io_take_into_inner", issue = "23755")]
+    #[stable(feature = "io_take_into_inner", since = "1.15.0")]
     pub fn into_inner(self) -> T {
         self.inner
     }
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index 6419a9ff683..1a65bee13b8 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -10,7 +10,7 @@
 
 use io::prelude::*;
 
-use cell::{RefCell, BorrowState};
+use cell::RefCell;
 use fmt;
 use io::lazy::Lazy;
 use io::{self, BufReader, LineWriter};
@@ -638,8 +638,8 @@ pub fn _print(args: fmt::Arguments) {
         LocalKeyState::Destroyed => stdout().write_fmt(args),
         LocalKeyState::Valid => {
             LOCAL_STDOUT.with(|s| {
-                if s.borrow_state() == BorrowState::Unused {
-                    if let Some(w) = s.borrow_mut().as_mut() {
+                if let Ok(mut borrowed) = s.try_borrow_mut() {
+                    if let Some(w) = borrowed.as_mut() {
                         return w.write_fmt(args);
                     }
                 }
diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs
index 9f51d3e87f3..63745388eb6 100644
--- a/src/libstd/sync/mpsc/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -316,7 +316,7 @@ pub struct Iter<'a, T: 'a> {
 ///
 /// This Iterator will never block the caller in order to wait for data to
 /// become available. Instead, it will return `None`.
-#[unstable(feature = "receiver_try_iter", issue = "34931")]
+#[stable(feature = "receiver_try_iter", since = "1.15.0")]
 pub struct TryIter<'a, T: 'a> {
     rx: &'a Receiver<T>
 }
@@ -1008,7 +1008,7 @@ impl<T> Receiver<T> {
     /// It will return `None` if there are no more pending values or if the
     /// channel has hung up. The iterator will never `panic!` or block the
     /// user by waiting for values.
-    #[unstable(feature = "receiver_try_iter", issue = "34931")]
+    #[stable(feature = "receiver_try_iter", since = "1.15.0")]
     pub fn try_iter(&self) -> TryIter<T> {
         TryIter { rx: self }
     }
@@ -1108,7 +1108,7 @@ impl<'a, T> Iterator for Iter<'a, T> {
     fn next(&mut self) -> Option<T> { self.rx.recv().ok() }
 }
 
-#[unstable(feature = "receiver_try_iter", issue = "34931")]
+#[stable(feature = "receiver_try_iter", since = "1.15.0")]
 impl<'a, T> Iterator for TryIter<'a, T> {
     type Item = T;
 
diff --git a/src/libstd/sys/redox/ext/process.rs b/src/libstd/sys/redox/ext/process.rs
index 1472242d3db..c59524974bf 100644
--- a/src/libstd/sys/redox/ext/process.rs
+++ b/src/libstd/sys/redox/ext/process.rs
@@ -56,7 +56,7 @@ pub trait CommandExt {
     /// When this closure is run, aspects such as the stdio file descriptors and
     /// working directory have successfully been changed, so output to these
     /// locations may not appear where intended.
-    #[unstable(feature = "process_exec", issue = "31398")]
+    #[stable(feature = "process_exec", since = "1.15.0")]
     fn before_exec<F>(&mut self, f: F) -> &mut process::Command
         where F: FnMut() -> io::Result<()> + Send + Sync + 'static;
 
diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs
index fcfab051588..900f463fa83 100644
--- a/src/libstd/sys/unix/ext/fs.rs
+++ b/src/libstd/sys/unix/ext/fs.rs
@@ -21,7 +21,7 @@ use sys_common::{FromInner, AsInner, AsInnerMut};
 use sys::platform::fs::MetadataExt as UnixMetadataExt;
 
 /// Unix-specific extensions to `File`
-#[unstable(feature = "file_offset", issue = "35918")]
+#[stable(feature = "file_offset", since = "1.15.0")]
 pub trait FileExt {
     /// Reads a number of bytes starting from a given offset.
     ///
@@ -34,7 +34,7 @@ pub trait FileExt {
     ///
     /// Note that similar to `File::read`, it is not an error to return with a
     /// short read.
-    #[unstable(feature = "file_offset", issue = "35918")]
+    #[stable(feature = "file_offset", since = "1.15.0")]
     fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
 
     /// Writes a number of bytes starting from a given offset.
@@ -51,11 +51,11 @@ pub trait FileExt {
     ///
     /// Note that similar to `File::write`, it is not an error to return a
     /// short write.
-    #[unstable(feature = "file_offset", issue = "35918")]
+    #[stable(feature = "file_offset", since = "1.15.0")]
     fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
 }
 
-#[unstable(feature = "file_offset", issue = "35918")]
+#[stable(feature = "file_offset", since = "1.15.0")]
 impl FileExt for fs::File {
     fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
         self.as_inner().read_at(buf, offset)
diff --git a/src/libstd/sys/unix/ext/mod.rs b/src/libstd/sys/unix/ext/mod.rs
index b2483f4e209..1be9f11b92c 100644
--- a/src/libstd/sys/unix/ext/mod.rs
+++ b/src/libstd/sys/unix/ext/mod.rs
@@ -50,7 +50,7 @@ pub mod prelude {
     pub use super::fs::{PermissionsExt, OpenOptionsExt, MetadataExt, FileTypeExt};
     #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
     pub use super::fs::DirEntryExt;
-    #[doc(no_inline)] #[unstable(feature = "file_offset", issue = "35918")]
+    #[doc(no_inline)] #[stable(feature = "file_offset", since = "1.15.0")]
     pub use super::fs::FileExt;
     #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
     pub use super::thread::JoinHandleExt;
diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs
index 3a7c59d4e6d..585dcbb9a34 100644
--- a/src/libstd/sys/unix/ext/process.rs
+++ b/src/libstd/sys/unix/ext/process.rs
@@ -56,7 +56,7 @@ pub trait CommandExt {
     /// When this closure is run, aspects such as the stdio file descriptors and
     /// working directory have successfully been changed, so output to these
     /// locations may not appear where intended.
-    #[unstable(feature = "process_exec", issue = "31398")]
+    #[stable(feature = "process_exec", since = "1.15.0")]
     fn before_exec<F>(&mut self, f: F) -> &mut process::Command
         where F: FnMut() -> io::Result<()> + Send + Sync + 'static;
 
diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs
index 1e2b8bf38fa..7fc04ad69d6 100644
--- a/src/libstd/sys/windows/ext/fs.rs
+++ b/src/libstd/sys/windows/ext/fs.rs
@@ -19,7 +19,7 @@ use sys;
 use sys_common::{AsInnerMut, AsInner};
 
 /// Windows-specific extensions to `File`
-#[unstable(feature = "file_offset", issue = "35918")]
+#[stable(feature = "file_offset", since = "1.15.0")]
 pub trait FileExt {
     /// Seeks to a given position and reads a number of bytes.
     ///
@@ -35,7 +35,7 @@ pub trait FileExt {
     /// Note that similar to `File::read`, it is not an error to return with a
     /// short read. When returning from such a short read, the file pointer is
     /// still updated.
-    #[unstable(feature = "file_offset", issue = "35918")]
+    #[stable(feature = "file_offset", since = "1.15.0")]
     fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
 
     /// Seeks to a given position and writes a number of bytes.
@@ -52,11 +52,11 @@ pub trait FileExt {
     /// Note that similar to `File::write`, it is not an error to return a
     /// short write. When returning from such a short write, the file pointer
     /// is still updated.
-    #[unstable(feature = "file_offset", issue = "35918")]
+    #[stable(feature = "file_offset", since = "1.15.0")]
     fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
 }
 
-#[unstable(feature = "file_offset", issue = "35918")]
+#[stable(feature = "file_offset", since = "1.15.0")]
 impl FileExt for fs::File {
     fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
         self.as_inner().read_at(buf, offset)
diff --git a/src/libstd/sys/windows/ext/mod.rs b/src/libstd/sys/windows/ext/mod.rs
index 932bb5e9564..f12e50cc923 100644
--- a/src/libstd/sys/windows/ext/mod.rs
+++ b/src/libstd/sys/windows/ext/mod.rs
@@ -36,6 +36,6 @@ pub mod prelude {
     pub use super::ffi::{OsStrExt, OsStringExt};
     #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
     pub use super::fs::{OpenOptionsExt, MetadataExt};
-    #[doc(no_inline)] #[unstable(feature = "file_offset", issue = "35918")]
+    #[doc(no_inline)] #[stable(feature = "file_offset", since = "1.15.0")]
     pub use super::fs::FileExt;
 }
diff --git a/src/libstd_unicode/char.rs b/src/libstd_unicode/char.rs
index 94599216db6..53dafadb5d5 100644
--- a/src/libstd_unicode/char.rs
+++ b/src/libstd_unicode/char.rs
@@ -448,8 +448,6 @@ impl char {
     /// In both of these examples, 'ß' takes two bytes to encode.
     ///
     /// ```
-    /// #![feature(unicode)]
-    ///
     /// let mut b = [0; 2];
     ///
     /// let result = 'ß'.encode_utf8(&mut b);
@@ -462,7 +460,6 @@ impl char {
     /// A buffer that's too small:
     ///
     /// ```
-    /// #![feature(unicode)]
     /// use std::thread;
     ///
     /// let result = thread::spawn(|| {
@@ -474,9 +471,7 @@ impl char {
     ///
     /// assert!(result.is_err());
     /// ```
-    #[unstable(feature = "unicode",
-               reason = "pending decision about Iterator/Writer/Reader",
-               issue = "27784")]
+    #[stable(feature = "unicode_encode_char", since = "1.15.0")]
     #[inline]
     pub fn encode_utf8(self, dst: &mut [u8]) -> &mut str {
         C::encode_utf8(self, dst)
@@ -495,8 +490,6 @@ impl char {
     /// In both of these examples, '𝕊' takes two `u16`s to encode.
     ///
     /// ```
-    /// #![feature(unicode)]
-    ///
     /// let mut b = [0; 2];
     ///
     /// let result = '𝕊'.encode_utf16(&mut b);
@@ -507,7 +500,6 @@ impl char {
     /// A buffer that's too small:
     ///
     /// ```
-    /// #![feature(unicode)]
     /// use std::thread;
     ///
     /// let result = thread::spawn(|| {
@@ -519,9 +511,7 @@ impl char {
     ///
     /// assert!(result.is_err());
     /// ```
-    #[unstable(feature = "unicode",
-               reason = "pending decision about Iterator/Writer/Reader",
-               issue = "27784")]
+    #[stable(feature = "unicode_encode_char", since = "1.15.0")]
     #[inline]
     pub fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] {
         C::encode_utf16(self, dst)
diff --git a/src/libstd_unicode/lib.rs b/src/libstd_unicode/lib.rs
index b086658ee0d..11724e74cda 100644
--- a/src/libstd_unicode/lib.rs
+++ b/src/libstd_unicode/lib.rs
@@ -39,7 +39,6 @@
 #![feature(lang_items)]
 #![feature(staged_api)]
 #![feature(try_from)]
-#![feature(unicode)]
 
 mod tables;
 mod u_str;