about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2015-01-12 18:40:19 -0800
committerBrian Anderson <banderson@mozilla.com>2015-01-21 16:16:18 -0800
commit94ca8a361026d1a622a961e8dc8cacc331ed1ac3 (patch)
tree58179e85714f0a1ee618a8a9982aadbeb65822cf /src/libstd
parent90aa581cff54ed1bb5f53ee2ead3764fca94fdf3 (diff)
downloadrust-94ca8a361026d1a622a961e8dc8cacc331ed1ac3.tar.gz
rust-94ca8a361026d1a622a961e8dc8cacc331ed1ac3.zip
Add 'feature' and 'since' to stability attributes
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/ascii.rs30
-rw-r--r--src/libstd/bool.rs2
-rw-r--r--src/libstd/collections/hash/map.rs129
-rw-r--r--src/libstd/collections/hash/set.rs105
-rw-r--r--src/libstd/collections/mod.rs8
-rw-r--r--src/libstd/dynamic_lib.rs2
-rw-r--r--src/libstd/error.rs15
-rw-r--r--src/libstd/failure.rs2
-rw-r--r--src/libstd/ffi/mod.rs5
-rw-r--r--src/libstd/fmt.rs7
-rw-r--r--src/libstd/io/comm_adapters.rs2
-rw-r--r--src/libstd/io/mem.rs3
-rw-r--r--src/libstd/io/mod.rs10
-rw-r--r--src/libstd/io/net/pipe.rs19
-rw-r--r--src/libstd/io/net/tcp.rs23
-rw-r--r--src/libstd/io/net/udp.rs21
-rw-r--r--src/libstd/io/process.rs3
-rw-r--r--src/libstd/lib.rs4
-rw-r--r--src/libstd/macros.rs14
-rw-r--r--src/libstd/num/f32.rs18
-rw-r--r--src/libstd/num/f64.rs18
-rw-r--r--src/libstd/num/float_macros.rs2
-rw-r--r--src/libstd/num/i16.rs2
-rw-r--r--src/libstd/num/i32.rs2
-rw-r--r--src/libstd/num/i64.rs2
-rw-r--r--src/libstd/num/i8.rs2
-rw-r--r--src/libstd/num/int.rs2
-rw-r--r--src/libstd/num/int_macros.rs2
-rw-r--r--src/libstd/num/isize.rs2
-rw-r--r--src/libstd/num/mod.rs168
-rw-r--r--src/libstd/num/u16.rs2
-rw-r--r--src/libstd/num/u32.rs2
-rw-r--r--src/libstd/num/u64.rs2
-rw-r--r--src/libstd/num/u8.rs2
-rw-r--r--src/libstd/num/uint.rs2
-rw-r--r--src/libstd/num/uint_macros.rs2
-rw-r--r--src/libstd/num/usize.rs2
-rw-r--r--src/libstd/os.rs2
-rw-r--r--src/libstd/path/mod.rs2
-rw-r--r--src/libstd/prelude/mod.rs4
-rw-r--r--src/libstd/prelude/v1.rs59
-rw-r--r--src/libstd/rand/mod.rs2
-rw-r--r--src/libstd/rt/mod.rs2
-rw-r--r--src/libstd/rt/unwind.rs2
-rw-r--r--src/libstd/rtdeps.rs2
-rw-r--r--src/libstd/sync/barrier.rs8
-rw-r--r--src/libstd/sync/condvar.rs40
-rw-r--r--src/libstd/sync/future.rs7
-rw-r--r--src/libstd/sync/mod.rs2
-rw-r--r--src/libstd/sync/mpsc/mod.rs56
-rw-r--r--src/libstd/sync/mpsc/mpsc_queue.rs4
-rw-r--r--src/libstd/sync/mpsc/select.rs13
-rw-r--r--src/libstd/sync/mpsc/spsc_queue.rs2
-rw-r--r--src/libstd/sync/mutex.rs35
-rw-r--r--src/libstd/sync/once.rs6
-rw-r--r--src/libstd/sync/poison.rs20
-rw-r--r--src/libstd/sync/rwlock.rs53
-rw-r--r--src/libstd/sync/semaphore.rs7
-rw-r--r--src/libstd/sync/task_pool.rs9
-rw-r--r--src/libstd/sys/unix/ext.rs2
-rw-r--r--src/libstd/sys/windows/ext.rs2
-rw-r--r--src/libstd/thread.rs58
-rw-r--r--src/libstd/thread_local/mod.rs17
-rw-r--r--src/libstd/thread_local/scoped.rs5
-rw-r--r--src/libstd/time/duration.rs2
-rw-r--r--src/libstd/tuple.rs2
-rw-r--r--src/libstd/unit.rs2
67 files changed, 593 insertions, 472 deletions
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index 77c2315194b..9e301bf9c04 100644
--- a/src/libstd/ascii.rs
+++ b/src/libstd/ascii.rs
@@ -12,7 +12,8 @@
 
 //! Operations on ASCII strings and characters
 
-#![unstable = "unsure about placement and naming"]
+#![unstable(feature = "unnamed_feature", since = "1.0.0",
+            reason = "unsure about placement and naming")]
 
 use iter::IteratorExt;
 use ops::FnMut;
@@ -22,7 +23,8 @@ use string::String;
 use vec::Vec;
 
 /// Extension methods for ASCII-subset only operations on owned strings
-#[unstable = "would prefer to do this in a more general way"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "would prefer to do this in a more general way")]
 pub trait OwnedAsciiExt {
     /// Convert the string to ASCII upper case:
     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
@@ -36,7 +38,8 @@ pub trait OwnedAsciiExt {
 }
 
 /// Extension methods for ASCII-subset only operations on string slices
-#[unstable = "would prefer to do this in a more general way"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "would prefer to do this in a more general way")]
 pub trait AsciiExt<T = Self> {
     /// Check if within the ASCII range.
     fn is_ascii(&self) -> bool;
@@ -57,7 +60,8 @@ pub trait AsciiExt<T = Self> {
     fn eq_ignore_ascii_case(&self, other: &Self) -> bool;
 }
 
-#[unstable = "would prefer to do this in a more general way"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "would prefer to do this in a more general way")]
 impl AsciiExt<String> for str {
     #[inline]
     fn is_ascii(&self) -> bool {
@@ -82,7 +86,8 @@ impl AsciiExt<String> for str {
     }
 }
 
-#[unstable = "would prefer to do this in a more general way"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "would prefer to do this in a more general way")]
 impl OwnedAsciiExt for String {
     #[inline]
     fn into_ascii_uppercase(self) -> String {
@@ -97,7 +102,8 @@ impl OwnedAsciiExt for String {
     }
 }
 
-#[unstable = "would prefer to do this in a more general way"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "would prefer to do this in a more general way")]
 impl AsciiExt<Vec<u8>> for [u8] {
     #[inline]
     fn is_ascii(&self) -> bool {
@@ -123,7 +129,8 @@ impl AsciiExt<Vec<u8>> for [u8] {
     }
 }
 
-#[unstable = "would prefer to do this in a more general way"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "would prefer to do this in a more general way")]
 impl OwnedAsciiExt for Vec<u8> {
     #[inline]
     fn into_ascii_uppercase(mut self) -> Vec<u8> {
@@ -142,7 +149,8 @@ impl OwnedAsciiExt for Vec<u8> {
     }
 }
 
-#[unstable = "would prefer to do this in a more general way"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "would prefer to do this in a more general way")]
 impl AsciiExt for u8 {
     #[inline]
     fn is_ascii(&self) -> bool {
@@ -165,7 +173,8 @@ impl AsciiExt for u8 {
     }
 }
 
-#[unstable = "would prefer to do this in a more general way"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "would prefer to do this in a more general way")]
 impl AsciiExt for char {
     #[inline]
     fn is_ascii(&self) -> bool {
@@ -207,7 +216,8 @@ impl AsciiExt for char {
 /// - Any other chars in the range [0x20,0x7e] are not escaped.
 /// - Any other chars are given hex escapes.
 /// - Unicode escapes are never generated by this function.
-#[unstable = "needs to be updated to use an iterator"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "needs to be updated to use an iterator")]
 pub fn escape_default<F>(c: u8, mut f: F) where
     F: FnMut(u8),
 {
diff --git a/src/libstd/bool.rs b/src/libstd/bool.rs
index bbaab5ee3db..6ec1299aac5 100644
--- a/src/libstd/bool.rs
+++ b/src/libstd/bool.rs
@@ -11,5 +11,5 @@
 //! The boolean type
 
 #![doc(primitive = "bool")]
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index d3ac632617d..6690d3bd374 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -296,7 +296,7 @@ fn test_resize_policy() {
 /// }
 /// ```
 #[derive(Clone)]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct HashMap<K, V, S = RandomState> {
     // All hashes are keyed on these values, to prevent hash collision attacks.
     hash_state: S,
@@ -499,7 +499,7 @@ impl<K: Hash<Hasher> + Eq, V> HashMap<K, V, RandomState> {
     /// let mut map: HashMap<&str, int> = HashMap::new();
     /// ```
     #[inline]
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn new() -> HashMap<K, V, RandomState> {
         Default::default()
     }
@@ -513,7 +513,7 @@ impl<K: Hash<Hasher> + Eq, V> HashMap<K, V, RandomState> {
     /// let mut map: HashMap<&str, int> = HashMap::with_capacity(10);
     /// ```
     #[inline]
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn with_capacity(capacity: uint) -> HashMap<K, V, RandomState> {
         HashMap::with_capacity_and_hash_state(capacity, Default::default())
     }
@@ -539,7 +539,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// map.insert(1i, 2u);
     /// ```
     #[inline]
-    #[unstable = "hasher stuff is unclear"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "hasher stuff is unclear")]
     pub fn with_hash_state(hash_state: S) -> HashMap<K, V, S> {
         HashMap {
             hash_state:    hash_state,
@@ -567,7 +567,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// map.insert(1i, 2u);
     /// ```
     #[inline]
-    #[unstable = "hasher stuff is unclear"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "hasher stuff is unclear")]
     pub fn with_capacity_and_hash_state(capacity: uint, hash_state: S)
                                         -> HashMap<K, V, S> {
         let resize_policy = DefaultResizePolicy::new();
@@ -591,7 +591,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// assert!(map.capacity() >= 100);
     /// ```
     #[inline]
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn capacity(&self) -> uint {
         self.resize_policy.usable_capacity(self.table.capacity())
     }
@@ -611,7 +611,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// let mut map: HashMap<&str, int> = HashMap::new();
     /// map.reserve(10);
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn reserve(&mut self, additional: uint) {
         let new_size = self.len().checked_add(additional).expect("capacity overflow");
         let min_cap = self.resize_policy.min_capacity(new_size);
@@ -723,7 +723,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// map.shrink_to_fit();
     /// assert!(map.capacity() >= 2);
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn shrink_to_fit(&mut self) {
         let min_capacity = self.resize_policy.min_capacity(self.len());
         let min_capacity = max(min_capacity.next_power_of_two(), INITIAL_CAPACITY);
@@ -817,7 +817,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     ///     println!("{}", key);
     /// }
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
         fn first<A, B>((a, _): (A, B)) -> A { a }
         let first: fn((&'a K,&'a V)) -> &'a K = first; // coerce to fn ptr
@@ -842,7 +842,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     ///     println!("{}", key);
     /// }
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn values<'a>(&'a self) -> Values<'a, K, V> {
         fn second<A, B>((_, b): (A, B)) -> B { b }
         let second: fn((&'a K,&'a V)) -> &'a V = second; // coerce to fn ptr
@@ -867,7 +867,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     ///     println!("key: {} val: {}", key, val);
     /// }
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn iter(&self) -> Iter<K, V> {
         Iter { inner: self.table.iter() }
     }
@@ -895,7 +895,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     ///     println!("key: {} val: {}", key, val);
     /// }
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn iter_mut(&mut self) -> IterMut<K, V> {
         IterMut { inner: self.table.iter_mut() }
     }
@@ -917,7 +917,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// // Not possible with .iter()
     /// let vec: Vec<(&str, int)> = map.into_iter().collect();
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn into_iter(self) -> IntoIter<K, V> {
         fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
         let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two;
@@ -928,7 +928,8 @@ impl<K, V, S, H> HashMap<K, V, S>
     }
 
     /// Gets the given key's corresponding entry in the map for in-place manipulation.
-    #[unstable = "precise API still being fleshed out"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "precise API still being fleshed out")]
     pub fn entry<'a>(&'a mut self, key: K) -> Entry<'a, K, V>
     {
         // Gotta resize now.
@@ -950,7 +951,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// a.insert(1u, "a");
     /// assert_eq!(a.len(), 1);
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn len(&self) -> uint { self.table.size() }
 
     /// Return true if the map contains no elements.
@@ -966,7 +967,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// assert!(!a.is_empty());
     /// ```
     #[inline]
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn is_empty(&self) -> bool { self.len() == 0 }
 
     /// Clears the map, returning all key-value pairs as an iterator. Keeps the
@@ -989,7 +990,8 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// assert!(a.is_empty());
     /// ```
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "matches collection reform specification, waiting for dust to settle")]
     pub fn drain(&mut self) -> Drain<K, V> {
         fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
         let last_two: fn((SafeHash, K, V)) -> (K, V) = last_two; // coerce to fn pointer
@@ -1012,7 +1014,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// a.clear();
     /// assert!(a.is_empty());
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     #[inline]
     pub fn clear(&mut self) {
         self.drain();
@@ -1034,7 +1036,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// assert_eq!(map.get(&1), Some(&"a"));
     /// assert_eq!(map.get(&2), None);
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
         where Q: Hash<H> + Eq + BorrowFrom<K>
     {
@@ -1057,7 +1059,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// assert_eq!(map.contains_key(&1), true);
     /// assert_eq!(map.contains_key(&2), false);
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
         where Q: Hash<H> + Eq + BorrowFrom<K>
     {
@@ -1083,7 +1085,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// }
     /// assert_eq!(map[1], "b");
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
         where Q: Hash<H> + Eq + BorrowFrom<K>
     {
@@ -1106,7 +1108,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// assert_eq!(map.insert(37, "c"), Some("b"));
     /// assert_eq!(map[37], "c");
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn insert(&mut self, k: K, v: V) -> Option<V> {
         let hash = self.make_hash(&k);
         self.reserve(1);
@@ -1135,7 +1137,7 @@ impl<K, V, S, H> HashMap<K, V, S>
     /// assert_eq!(map.remove(&1), Some("a"));
     /// assert_eq!(map.remove(&1), None);
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
         where Q: Hash<H> + Eq + BorrowFrom<K>
     {
@@ -1208,14 +1210,14 @@ impl<K, V, S, H> PartialEq for HashMap<K, V, S>
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<K, V, S, H> Eq for HashMap<K, V, S>
     where K: Eq + Hash<H>, V: Eq,
           S: HashState<Hasher=H>,
           H: hash::Hasher<Output=u64>
 {}
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<K, V, S, H> Show for HashMap<K, V, S>
     where K: Eq + Hash<H> + Show, V: Show,
           S: HashState<Hasher=H>,
@@ -1233,7 +1235,7 @@ impl<K, V, S, H> Show for HashMap<K, V, S>
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<K, V, S, H> Default for HashMap<K, V, S>
     where K: Eq + Hash<H>,
           S: HashState<Hasher=H> + Default,
@@ -1244,7 +1246,7 @@ impl<K, V, S, H> Default for HashMap<K, V, S>
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<K, Q: ?Sized, V, S, H> Index<Q> for HashMap<K, V, S>
     where K: Eq + Hash<H>,
           Q: Eq + Hash<H> + BorrowFrom<K>,
@@ -1259,7 +1261,7 @@ impl<K, Q: ?Sized, V, S, H> Index<Q> for HashMap<K, V, S>
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<K, V, S, H, Q: ?Sized> IndexMut<Q> for HashMap<K, V, S>
     where K: Eq + Hash<H>,
           Q: Eq + Hash<H> + BorrowFrom<K>,
@@ -1275,7 +1277,7 @@ impl<K, V, S, H, Q: ?Sized> IndexMut<Q> for HashMap<K, V, S>
 }
 
 /// HashMap iterator
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Iter<'a, K: 'a, V: 'a> {
     inner: table::Iter<'a, K, V>
 }
@@ -1290,13 +1292,13 @@ impl<'a, K, V> Clone for Iter<'a, K, V> {
 }
 
 /// HashMap mutable values iterator
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct IterMut<'a, K: 'a, V: 'a> {
     inner: table::IterMut<'a, K, V>
 }
 
 /// HashMap move iterator
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct IntoIter<K, V> {
     inner: iter::Map<
         (SafeHash, K, V),
@@ -1307,7 +1309,7 @@ pub struct IntoIter<K, V> {
 }
 
 /// HashMap keys iterator
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Keys<'a, K: 'a, V: 'a> {
     inner: Map<(&'a K, &'a V), &'a K, Iter<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>
 }
@@ -1322,7 +1324,7 @@ impl<'a, K, V> Clone for Keys<'a, K, V> {
 }
 
 /// HashMap values iterator
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Values<'a, K: 'a, V: 'a> {
     inner: Map<(&'a K, &'a V), &'a V, Iter<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>
 }
@@ -1337,7 +1339,8 @@ impl<'a, K, V> Clone for Values<'a, K, V> {
 }
 
 /// HashMap drain iterator
-#[unstable = "matches collection reform specification, waiting for dust to settle"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "matches collection reform specification, waiting for dust to settle")]
 pub struct Drain<'a, K: 'a, V: 'a> {
     inner: iter::Map<
         (SafeHash, K, V),
@@ -1348,13 +1351,15 @@ pub struct Drain<'a, K: 'a, V: 'a> {
 }
 
 /// A view into a single occupied location in a HashMap
-#[unstable = "precise API still being fleshed out"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "precise API still being fleshed out")]
 pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
     elem: FullBucket<K, V, &'a mut RawTable<K, V>>,
 }
 
 /// A view into a single empty location in a HashMap
-#[unstable = "precise API still being fleshed out"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "precise API still being fleshed out")]
 pub struct VacantEntry<'a, K: 'a, V: 'a> {
     hash: SafeHash,
     key: K,
@@ -1362,7 +1367,8 @@ pub struct VacantEntry<'a, K: 'a, V: 'a> {
 }
 
 /// A view into a single location in a map, which may be vacant or occupied
-#[unstable = "precise API still being fleshed out"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "precise API still being fleshed out")]
 pub enum Entry<'a, K: 'a, V: 'a> {
     /// An occupied Entry
     Occupied(OccupiedEntry<'a, K, V>),
@@ -1379,79 +1385,80 @@ enum VacantEntryState<K, V, M> {
     NoElem(EmptyBucket<K, V, M>),
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, K, V> Iterator for Iter<'a, K, V> {
     type Item = (&'a K, &'a V);
 
     #[inline] fn next(&mut self) -> Option<(&'a K, &'a V)> { self.inner.next() }
     #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
     #[inline] fn len(&self) -> usize { self.inner.len() }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, K, V> Iterator for IterMut<'a, K, V> {
     type Item = (&'a K, &'a mut V);
 
     #[inline] fn next(&mut self) -> Option<(&'a K, &'a mut V)> { self.inner.next() }
     #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
     #[inline] fn len(&self) -> usize { self.inner.len() }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<K, V> Iterator for IntoIter<K, V> {
     type Item = (K, V);
 
     #[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() }
     #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<K, V> ExactSizeIterator for IntoIter<K, V> {
     #[inline] fn len(&self) -> usize { self.inner.len() }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, K, V> Iterator for Keys<'a, K, V> {
     type Item = &'a K;
 
     #[inline] fn next(&mut self) -> Option<(&'a K)> { self.inner.next() }
     #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {
     #[inline] fn len(&self) -> usize { self.inner.len() }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, K, V> Iterator for Values<'a, K, V> {
     type Item = &'a V;
 
     #[inline] fn next(&mut self) -> Option<(&'a V)> { self.inner.next() }
     #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {
     #[inline] fn len(&self) -> usize { self.inner.len() }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, K, V> Iterator for Drain<'a, K, V> {
     type Item = (K, V);
 
     #[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() }
     #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
     #[inline] fn len(&self) -> usize { self.inner.len() }
 }
 
-#[unstable = "matches collection reform v2 specification, waiting for dust to settle"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "matches collection reform v2 specification, waiting for dust to settle")]
 impl<'a, K, V> Entry<'a, K, V> {
     /// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
     pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, K, V>> {
@@ -1462,7 +1469,8 @@ impl<'a, K, V> Entry<'a, K, V> {
     }
 }
 
-#[unstable = "matches collection reform v2 specification, waiting for dust to settle"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "matches collection reform v2 specification, waiting for dust to settle")]
 impl<'a, K, V> OccupiedEntry<'a, K, V> {
     /// Gets a reference to the value in the entry
     pub fn get(&self) -> &V {
@@ -1493,7 +1501,8 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
     }
 }
 
-#[unstable = "matches collection reform v2 specification, waiting for dust to settle"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "matches collection reform v2 specification, waiting for dust to settle")]
 impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
     /// Sets the value of the entry with the VacantEntry's key,
     /// and returns a mutable reference to it
@@ -1509,7 +1518,7 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<K, V, S, H> FromIterator<(K, V)> for HashMap<K, V, S>
     where K: Eq + Hash<H>,
           S: HashState<Hasher=H> + Default,
@@ -1524,7 +1533,7 @@ impl<K, V, S, H> FromIterator<(K, V)> for HashMap<K, V, S>
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<K, V, S, H> Extend<(K, V)> for HashMap<K, V, S>
     where K: Eq + Hash<H>,
           S: HashState<Hasher=H>,
@@ -1545,13 +1554,15 @@ impl<K, V, S, H> Extend<(K, V)> for HashMap<K, V, S>
 /// instances are unlikely to produce the same result for the same values.
 #[derive(Clone)]
 #[allow(missing_copy_implementations)]
-#[unstable = "hashing an hash maps may be altered"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "hashing an hash maps may be altered")]
 pub struct RandomState {
     k0: u64,
     k1: u64,
 }
 
-#[unstable = "hashing an hash maps may be altered"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "hashing an hash maps may be altered")]
 impl RandomState {
     /// Construct a new `RandomState` that is initialized with random keys.
     #[inline]
@@ -1561,7 +1572,8 @@ impl RandomState {
     }
 }
 
-#[unstable = "hashing an hash maps may be altered"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "hashing an hash maps may be altered")]
 impl HashState for RandomState {
     type Hasher = Hasher;
     fn hasher(&self) -> Hasher {
@@ -1569,7 +1581,8 @@ impl HashState for RandomState {
     }
 }
 
-#[unstable = "hashing an hash maps may be altered"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "hashing an hash maps may be altered")]
 impl Default for RandomState {
     #[inline]
     fn default() -> RandomState {
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index 1293f45161d..c4fecc00bbd 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -90,7 +90,7 @@ use super::state::HashState;
 /// }
 /// ```
 #[derive(Clone)]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct HashSet<T, S = RandomState> {
     map: HashMap<T, (), S>
 }
@@ -105,7 +105,7 @@ impl<T: Hash<Hasher> + Eq> HashSet<T, RandomState> {
     /// let mut set: HashSet<int> = HashSet::new();
     /// ```
     #[inline]
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn new() -> HashSet<T, RandomState> {
         HashSet::with_capacity(INITIAL_CAPACITY)
     }
@@ -120,7 +120,7 @@ impl<T: Hash<Hasher> + Eq> HashSet<T, RandomState> {
     /// let mut set: HashSet<int> = HashSet::with_capacity(10);
     /// ```
     #[inline]
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn with_capacity(capacity: uint) -> HashSet<T, RandomState> {
         HashSet { map: HashMap::with_capacity(capacity) }
     }
@@ -147,7 +147,7 @@ impl<T, S, H> HashSet<T, S>
     /// set.insert(2u);
     /// ```
     #[inline]
-    #[unstable = "hasher stuff is unclear"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "hasher stuff is unclear")]
     pub fn with_hash_state(hash_state: S) -> HashSet<T, S> {
         HashSet::with_capacity_and_hash_state(INITIAL_CAPACITY, hash_state)
     }
@@ -171,7 +171,7 @@ impl<T, S, H> HashSet<T, S>
     /// set.insert(1i);
     /// ```
     #[inline]
-    #[unstable = "hasher stuff is unclear"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "hasher stuff is unclear")]
     pub fn with_capacity_and_hash_state(capacity: uint, hash_state: S)
                                         -> HashSet<T, S> {
         HashSet {
@@ -189,7 +189,7 @@ impl<T, S, H> HashSet<T, S>
     /// assert!(set.capacity() >= 100);
     /// ```
     #[inline]
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn capacity(&self) -> uint {
         self.map.capacity()
     }
@@ -209,7 +209,7 @@ impl<T, S, H> HashSet<T, S>
     /// let mut set: HashSet<int> = HashSet::new();
     /// set.reserve(10);
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn reserve(&mut self, additional: uint) {
         self.map.reserve(additional)
     }
@@ -230,7 +230,7 @@ impl<T, S, H> HashSet<T, S>
     /// set.shrink_to_fit();
     /// assert!(set.capacity() >= 2);
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn shrink_to_fit(&mut self) {
         self.map.shrink_to_fit()
     }
@@ -251,7 +251,7 @@ impl<T, S, H> HashSet<T, S>
     ///     println!("{}", x);
     /// }
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn iter(&self) -> Iter<T> {
         Iter { iter: self.map.keys() }
     }
@@ -276,7 +276,7 @@ impl<T, S, H> HashSet<T, S>
     ///     println!("{}", x);
     /// }
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn into_iter(self) -> IntoIter<T> {
         fn first<A, B>((a, _): (A, B)) -> A { a }
         let first: fn((T, ())) -> T = first;
@@ -306,7 +306,7 @@ impl<T, S, H> HashSet<T, S>
     /// let diff: HashSet<int> = b.difference(&a).map(|&x| x).collect();
     /// assert_eq!(diff, [4i].iter().map(|&x| x).collect());
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn difference<'a>(&'a self, other: &'a HashSet<T, S>) -> Difference<'a, T, S> {
         Difference {
             iter: self.iter(),
@@ -334,7 +334,7 @@ impl<T, S, H> HashSet<T, S>
     /// assert_eq!(diff1, diff2);
     /// assert_eq!(diff1, [1i, 4].iter().map(|&x| x).collect());
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet<T, S>)
         -> SymmetricDifference<'a, T, S> {
         SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) }
@@ -357,7 +357,7 @@ impl<T, S, H> HashSet<T, S>
     /// let diff: HashSet<int> = a.intersection(&b).map(|&x| x).collect();
     /// assert_eq!(diff, [2i, 3].iter().map(|&x| x).collect());
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn intersection<'a>(&'a self, other: &'a HashSet<T, S>) -> Intersection<'a, T, S> {
         Intersection {
             iter: self.iter(),
@@ -382,7 +382,7 @@ impl<T, S, H> HashSet<T, S>
     /// let diff: HashSet<int> = a.union(&b).map(|&x| x).collect();
     /// assert_eq!(diff, [1i, 2, 3, 4].iter().map(|&x| x).collect());
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn union<'a>(&'a self, other: &'a HashSet<T, S>) -> Union<'a, T, S> {
         Union { iter: self.iter().chain(other.difference(self)) }
     }
@@ -399,7 +399,7 @@ impl<T, S, H> HashSet<T, S>
     /// v.insert(1u);
     /// assert_eq!(v.len(), 1);
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn len(&self) -> uint { self.map.len() }
 
     /// Returns true if the set contains no elements
@@ -414,12 +414,13 @@ impl<T, S, H> HashSet<T, S>
     /// v.insert(1u);
     /// assert!(!v.is_empty());
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn is_empty(&self) -> bool { self.map.len() == 0 }
 
     /// Clears the set, returning all elements in an iterator.
     #[inline]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "matches collection reform specification, waiting for dust to settle")]
     pub fn drain(&mut self) -> Drain<T> {
         fn first<A, B>((a, _): (A, B)) -> A { a }
         let first: fn((T, ())) -> T = first; // coerce to fn pointer
@@ -439,7 +440,7 @@ impl<T, S, H> HashSet<T, S>
     /// v.clear();
     /// assert!(v.is_empty());
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn clear(&mut self) { self.map.clear() }
 
     /// Returns `true` if the set contains a value.
@@ -457,7 +458,7 @@ impl<T, S, H> HashSet<T, S>
     /// assert_eq!(set.contains(&1), true);
     /// assert_eq!(set.contains(&4), false);
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
         where Q: BorrowFrom<T> + Hash<H> + Eq
     {
@@ -481,7 +482,7 @@ impl<T, S, H> HashSet<T, S>
     /// b.insert(1);
     /// assert_eq!(a.is_disjoint(&b), false);
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn is_disjoint(&self, other: &HashSet<T, S>) -> bool {
         self.iter().all(|v| !other.contains(v))
     }
@@ -502,7 +503,7 @@ impl<T, S, H> HashSet<T, S>
     /// set.insert(4);
     /// assert_eq!(set.is_subset(&sup), false);
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn is_subset(&self, other: &HashSet<T, S>) -> bool {
         self.iter().all(|v| other.contains(v))
     }
@@ -527,7 +528,7 @@ impl<T, S, H> HashSet<T, S>
     /// assert_eq!(set.is_superset(&sub), true);
     /// ```
     #[inline]
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn is_superset(&self, other: &HashSet<T, S>) -> bool {
         other.is_subset(self)
     }
@@ -546,7 +547,7 @@ impl<T, S, H> HashSet<T, S>
     /// assert_eq!(set.insert(2), false);
     /// assert_eq!(set.len(), 1);
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none() }
 
     /// Removes a value from the set. Returns `true` if the value was
@@ -567,7 +568,7 @@ impl<T, S, H> HashSet<T, S>
     /// assert_eq!(set.remove(&2), true);
     /// assert_eq!(set.remove(&2), false);
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
         where Q: BorrowFrom<T> + Hash<H> + Eq
     {
@@ -575,7 +576,7 @@ impl<T, S, H> HashSet<T, S>
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T, S, H> PartialEq for HashSet<T, S>
     where T: Eq + Hash<H>,
           S: HashState<Hasher=H>,
@@ -588,14 +589,14 @@ impl<T, S, H> PartialEq for HashSet<T, S>
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T, S, H> Eq for HashSet<T, S>
     where T: Eq + Hash<H>,
           S: HashState<Hasher=H>,
           H: hash::Hasher<Output=u64>
 {}
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T, S, H> fmt::Show for HashSet<T, S>
     where T: Eq + Hash<H> + fmt::Show,
           S: HashState<Hasher=H>,
@@ -613,7 +614,7 @@ impl<T, S, H> fmt::Show for HashSet<T, S>
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T, S, H> FromIterator<T> for HashSet<T, S>
     where T: Eq + Hash<H>,
           S: HashState<Hasher=H> + Default,
@@ -627,7 +628,7 @@ impl<T, S, H> FromIterator<T> for HashSet<T, S>
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T, S, H> Extend<T> for HashSet<T, S>
     where T: Eq + Hash<H>,
           S: HashState<Hasher=H>,
@@ -640,19 +641,19 @@ impl<T, S, H> Extend<T> for HashSet<T, S>
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T, S, H> Default for HashSet<T, S>
     where T: Eq + Hash<H>,
           S: HashState<Hasher=H> + Default,
           H: hash::Hasher<Output=u64>
 {
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn default() -> HashSet<T, S> {
         HashSet::with_hash_state(Default::default())
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, 'b, T, S, H> BitOr<&'b HashSet<T, S>> for &'a HashSet<T, S>
     where T: Eq + Hash<H> + Clone,
           S: HashState<Hasher=H> + Default,
@@ -685,7 +686,7 @@ impl<'a, 'b, T, S, H> BitOr<&'b HashSet<T, S>> for &'a HashSet<T, S>
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, 'b, T, S, H> BitAnd<&'b HashSet<T, S>> for &'a HashSet<T, S>
     where T: Eq + Hash<H> + Clone,
           S: HashState<Hasher=H> + Default,
@@ -718,7 +719,7 @@ impl<'a, 'b, T, S, H> BitAnd<&'b HashSet<T, S>> for &'a HashSet<T, S>
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, 'b, T, S, H> BitXor<&'b HashSet<T, S>> for &'a HashSet<T, S>
     where T: Eq + Hash<H> + Clone,
           S: HashState<Hasher=H> + Default,
@@ -751,7 +752,7 @@ impl<'a, 'b, T, S, H> BitXor<&'b HashSet<T, S>> for &'a HashSet<T, S>
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, 'b, T, S, H> Sub<&'b HashSet<T, S>> for &'a HashSet<T, S>
     where T: Eq + Hash<H> + Clone,
           S: HashState<Hasher=H> + Default,
@@ -785,25 +786,25 @@ impl<'a, 'b, T, S, H> Sub<&'b HashSet<T, S>> for &'a HashSet<T, S>
 }
 
 /// HashSet iterator
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Iter<'a, K: 'a> {
     iter: Keys<'a, K, ()>
 }
 
 /// HashSet move iterator
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct IntoIter<K> {
     iter: Map<(K, ()), K, map::IntoIter<K, ()>, fn((K, ())) -> K>
 }
 
 /// HashSet drain iterator
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Drain<'a, K: 'a> {
     iter: Map<(K, ()), K, map::Drain<'a, K, ()>, fn((K, ())) -> K>,
 }
 
 /// Intersection iterator
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Intersection<'a, T: 'a, S: 'a> {
     // iterator of the first set
     iter: Iter<'a, T>,
@@ -812,7 +813,7 @@ pub struct Intersection<'a, T: 'a, S: 'a> {
 }
 
 /// Difference iterator
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Difference<'a, T: 'a, S: 'a> {
     // iterator of the first set
     iter: Iter<'a, T>,
@@ -821,54 +822,54 @@ pub struct Difference<'a, T: 'a, S: 'a> {
 }
 
 /// Symmetric difference iterator.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct SymmetricDifference<'a, T: 'a, S: 'a> {
     iter: Chain<Difference<'a, T, S>, Difference<'a, T, S>>
 }
 
 /// Set union iterator.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Union<'a, T: 'a, S: 'a> {
     iter: Chain<Iter<'a, T>, Difference<'a, T, S>>
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, K> Iterator for Iter<'a, K> {
     type Item = &'a K;
 
     fn next(&mut self) -> Option<&'a K> { self.iter.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
 }
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, K> ExactSizeIterator for Iter<'a, K> {
     fn len(&self) -> usize { self.iter.len() }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<K> Iterator for IntoIter<K> {
     type Item = K;
 
     fn next(&mut self) -> Option<K> { self.iter.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
 }
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<K> ExactSizeIterator for IntoIter<K> {
     fn len(&self) -> usize { self.iter.len() }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, K> Iterator for Drain<'a, K> {
     type Item = K;
 
     fn next(&mut self) -> Option<K> { self.iter.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
 }
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, K> ExactSizeIterator for Drain<'a, K> {
     fn len(&self) -> usize { self.iter.len() }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, T, S, H> Iterator for Intersection<'a, T, S>
     where T: Eq + Hash<H>,
           S: HashState<Hasher=H>,
@@ -893,7 +894,7 @@ impl<'a, T, S, H> Iterator for Intersection<'a, T, S>
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, T, S, H> Iterator for Difference<'a, T, S>
     where T: Eq + Hash<H>,
           S: HashState<Hasher=H>,
@@ -918,7 +919,7 @@ impl<'a, T, S, H> Iterator for Difference<'a, T, S>
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, T, S, H> Iterator for SymmetricDifference<'a, T, S>
     where T: Eq + Hash<H>,
           S: HashState<Hasher=H>,
@@ -930,7 +931,7 @@ impl<'a, T, S, H> Iterator for SymmetricDifference<'a, T, S>
     fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, T, S, H> Iterator for Union<'a, T, S>
     where T: Eq + Hash<H>,
           S: HashState<Hasher=H>,
diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs
index f085fd259de..2e2d70546ae 100644
--- a/src/libstd/collections/mod.rs
+++ b/src/libstd/collections/mod.rs
@@ -309,7 +309,7 @@
 //! }
 //! ```
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 
 pub use core_collections::Bound;
 pub use core_collections::{BinaryHeap, Bitv, BitvSet, BTreeMap, BTreeSet};
@@ -323,13 +323,13 @@ pub use self::hash_set::HashSet;
 
 mod hash;
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub mod hash_map {
     //! A hashmap
     pub use super::hash::map::*;
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub mod hash_set {
     //! A hashset
     pub use super::hash::set::*;
@@ -337,7 +337,7 @@ pub mod hash_set {
 
 /// Experimental support for providing custom hash algorithms to a HashMap and
 /// HashSet.
-#[unstable = "module was recently added"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "module was recently added")]
 pub mod hash_state {
     pub use super::hash::state::*;
 }
diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
index db1239ae5b5..493f5ad2dc6 100644
--- a/src/libstd/dynamic_lib.rs
+++ b/src/libstd/dynamic_lib.rs
@@ -12,7 +12,7 @@
 //!
 //! A simple wrapper over the platform's dynamic library facilities
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 #![allow(missing_docs)]
 
 use prelude::v1::*;
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index ff128461978..91603fb7119 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -78,7 +78,7 @@
 //! }
 //! ```
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 
 use prelude::v1::*;
 
@@ -86,7 +86,8 @@ use str::Utf8Error;
 use string::{FromUtf8Error, FromUtf16Error};
 
 /// Base functionality for all errors in Rust.
-#[unstable = "the exact API of this trait may change"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "the exact API of this trait may change")]
 pub trait Error {
     /// A short description of the error; usually a static string.
     fn description(&self) -> &str;
@@ -99,21 +100,21 @@ pub trait Error {
 }
 
 /// A trait for types that can be converted from a given error type `E`.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub trait FromError<E> {
     /// Perform the conversion.
     fn from_error(err: E) -> Self;
 }
 
 // Any type is convertable from itself
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<E> FromError<E> for E {
     fn from_error(err: E) -> E {
         err
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl Error for Utf8Error {
     fn description(&self) -> &str {
         match *self {
@@ -125,13 +126,13 @@ impl Error for Utf8Error {
     fn detail(&self) -> Option<String> { Some(self.to_string()) }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl Error for FromUtf8Error {
     fn description(&self) -> &str { "invalid utf-8" }
     fn detail(&self) -> Option<String> { Some(self.to_string()) }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl Error for FromUtf16Error {
     fn description(&self) -> &str { "invalid utf-16" }
 }
diff --git a/src/libstd/failure.rs b/src/libstd/failure.rs
index 54191cf2404..e6b3348e690 100644
--- a/src/libstd/failure.rs
+++ b/src/libstd/failure.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 
 use prelude::v1::*;
 
diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs
index cc86f804e3e..6017a62e3be 100644
--- a/src/libstd/ffi/mod.rs
+++ b/src/libstd/ffi/mod.rs
@@ -10,8 +10,9 @@
 
 //! Utilities related to FFI bindings.
 
-#![unstable = "module just underwent fairly large reorganization and the dust \
-               still needs to settle"]
+#![unstable(feature = "unnamed_feature", since = "1.0.0",
+            reason = "module just underwent fairly large reorganization and the dust \
+                      still needs to settle")]
 
 pub use self::c_str::CString;
 pub use self::c_str::c_str_to_bytes;
diff --git a/src/libstd/fmt.rs b/src/libstd/fmt.rs
index 88fb983361a..d28e84f3cdd 100644
--- a/src/libstd/fmt.rs
+++ b/src/libstd/fmt.rs
@@ -403,7 +403,7 @@
 //! them with the same character. For example, the `{` character is escaped with
 //! `{{` and the `}` character is escaped with `}}`.
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 
 use string;
 
@@ -432,8 +432,9 @@ pub use core::fmt::{argument, argumentuint};
 /// let s = fmt::format(format_args!("Hello, {}!", "world"));
 /// assert_eq!(s, "Hello, world!".to_string());
 /// ```
-#[unstable = "this is an implementation detail of format! and should not \
-                  be called directly"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "this is an implementation detail of format! and should not \
+                     be called directly")]
 pub fn format(args: Arguments) -> string::String {
     let mut output = string::String::new();
     let _ = write!(&mut output, "{}", args);
diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs
index 4b0014c68f7..2cdad79c584 100644
--- a/src/libstd/io/comm_adapters.rs
+++ b/src/libstd/io/comm_adapters.rs
@@ -134,7 +134,7 @@ impl ChanWriter {
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl Clone for ChanWriter {
     fn clone(&self) -> ChanWriter {
         ChanWriter { tx: self.tx.clone() }
diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs
index ee05a9e5596..43d7db6cbbf 100644
--- a/src/libstd/io/mem.rs
+++ b/src/libstd/io/mem.rs
@@ -62,7 +62,8 @@ impl Writer for Vec<u8> {
 ///
 /// assert_eq!(w.into_inner(), vec!(0, 1, 2));
 /// ```
-#[deprecated = "use the Vec<u8> Writer implementation directly"]
+#[deprecated(feature = "oldstuff", since = "1.0.0",
+             reason = "use the Vec<u8> Writer implementation directly")]
 #[derive(Clone)]
 pub struct MemWriter {
     buf: Vec<u8>,
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index dc21416df7b..f680f896238 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -219,7 +219,7 @@
 //! concerned with error handling; instead its caller is responsible for
 //! responding to errors that may occur while attempting to read the numbers.
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 #![deny(unused_must_use)]
 
 pub use self::SeekStyle::*;
@@ -1744,7 +1744,7 @@ pub struct FileStat {
     ///
     /// Usage of this field is discouraged, but if access is desired then the
     /// fields are located here.
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub unstable: UnstableFileStat,
 }
 
@@ -1752,7 +1752,7 @@ pub struct FileStat {
 /// returned from a `stat` syscall which is not contained in the `FileStat`
 /// structure. This information is not necessarily platform independent, and may
 /// have different meanings or no meaning at all on some platforms.
-#[unstable]
+#[unstable(feature = "unnamed_feature", since = "1.0.0")]
 #[derive(Copy, Hash)]
 pub struct UnstableFileStat {
     /// The ID of the device containing the file.
@@ -1815,9 +1815,9 @@ bitflags! {
 }
 
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl Default for FilePermission {
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     #[inline]
     fn default() -> FilePermission { FilePermission::empty() }
 }
diff --git a/src/libstd/io/net/pipe.rs b/src/libstd/io/net/pipe.rs
index 61d164d21e3..6705b22c92f 100644
--- a/src/libstd/io/net/pipe.rs
+++ b/src/libstd/io/net/pipe.rs
@@ -68,7 +68,8 @@ impl UnixStream {
     ///
     /// If a `timeout` with zero or negative duration is specified then
     /// the function returns `Err`, with the error kind set to `TimedOut`.
-    #[unstable = "the timeout argument is likely to change types"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "the timeout argument is likely to change types")]
     pub fn connect_timeout<P>(path: P, timeout: Duration)
                               -> IoResult<UnixStream>
                               where P: BytesContainer {
@@ -107,7 +108,8 @@ impl UnixStream {
     /// Sets the read/write timeout for this socket.
     ///
     /// For more information, see `TcpStream::set_timeout`
-    #[unstable = "the timeout argument may change in type and value"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "the timeout argument may change in type and value")]
     pub fn set_timeout(&mut self, timeout_ms: Option<u64>) {
         self.inner.set_timeout(timeout_ms)
     }
@@ -115,7 +117,8 @@ impl UnixStream {
     /// Sets the read timeout for this socket.
     ///
     /// For more information, see `TcpStream::set_timeout`
-    #[unstable = "the timeout argument may change in type and value"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "the timeout argument may change in type and value")]
     pub fn set_read_timeout(&mut self, timeout_ms: Option<u64>) {
         self.inner.set_read_timeout(timeout_ms)
     }
@@ -123,7 +126,8 @@ impl UnixStream {
     /// Sets the write timeout for this socket.
     ///
     /// For more information, see `TcpStream::set_timeout`
-    #[unstable = "the timeout argument may change in type and value"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "the timeout argument may change in type and value")]
     pub fn set_write_timeout(&mut self, timeout_ms: Option<u64>) {
         self.inner.set_write_timeout(timeout_ms)
     }
@@ -217,8 +221,9 @@ impl UnixAcceptor {
     /// When using this method, it is likely necessary to reset the timeout as
     /// appropriate, the timeout specified is specific to this object, not
     /// specific to the next request.
-    #[unstable = "the name and arguments to this function are likely \
-                      to change"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "the name and arguments to this function are likely \
+                         to change")]
     pub fn set_timeout(&mut self, timeout_ms: Option<u64>) {
         self.inner.set_timeout(timeout_ms)
     }
@@ -227,7 +232,7 @@ impl UnixAcceptor {
     ///
     /// This function has the same semantics as `TcpAcceptor::close_accept`, and
     /// more information can be found in that documentation.
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn close_accept(&mut self) -> IoResult<()> {
         self.inner.close_accept()
     }
diff --git a/src/libstd/io/net/tcp.rs b/src/libstd/io/net/tcp.rs
index 4978085fa4f..180deae6a25 100644
--- a/src/libstd/io/net/tcp.rs
+++ b/src/libstd/io/net/tcp.rs
@@ -85,7 +85,8 @@ impl TcpStream {
     ///
     /// If a `timeout` with zero or negative duration is specified then
     /// the function returns `Err`, with the error kind set to `TimedOut`.
-    #[unstable = "the timeout argument may eventually change types"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "the timeout argument may eventually change types")]
     pub fn connect_timeout<A: ToSocketAddr>(addr: A,
                                             timeout: Duration) -> IoResult<TcpStream> {
         if timeout <= Duration::milliseconds(0) {
@@ -109,7 +110,7 @@ impl TcpStream {
     }
 
     /// Sets the nodelay flag on this connection to the boolean specified
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn set_nodelay(&mut self, nodelay: bool) -> IoResult<()> {
         self.inner.set_nodelay(nodelay)
     }
@@ -119,7 +120,7 @@ impl TcpStream {
     /// If the value specified is `None`, then the keepalive flag is cleared on
     /// this connection. Otherwise, the keepalive timeout will be set to the
     /// specified time, in seconds.
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn set_keepalive(&mut self, delay_in_seconds: Option<uint>) -> IoResult<()> {
         self.inner.set_keepalive(delay_in_seconds)
     }
@@ -187,7 +188,8 @@ impl TcpStream {
     ///
     /// For clarification on the semantics of interrupting a read and a write,
     /// take a look at `set_read_timeout` and `set_write_timeout`.
-    #[unstable = "the timeout argument may change in type and value"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "the timeout argument may change in type and value")]
     pub fn set_timeout(&mut self, timeout_ms: Option<u64>) {
         self.inner.set_timeout(timeout_ms)
     }
@@ -204,7 +206,8 @@ impl TcpStream {
     /// action is taken. Otherwise, the read operation will be scheduled to
     /// promptly return. If a timeout error is returned, then no data was read
     /// during the timeout period.
-    #[unstable = "the timeout argument may change in type and value"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "the timeout argument may change in type and value")]
     pub fn set_read_timeout(&mut self, timeout_ms: Option<u64>) {
         self.inner.set_read_timeout(timeout_ms)
     }
@@ -231,7 +234,8 @@ impl TcpStream {
     /// does not know how many bytes were written as part of the timeout
     /// operation. It may be the case that bytes continue to be written in an
     /// asynchronous fashion after the call to write returns.
-    #[unstable = "the timeout argument may change in type and value"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "the timeout argument may change in type and value")]
     pub fn set_write_timeout(&mut self, timeout_ms: Option<u64>) {
         self.inner.set_write_timeout(timeout_ms)
     }
@@ -395,8 +399,9 @@ impl TcpAcceptor {
     /// a.set_timeout(None);
     /// let socket = a.accept();
     /// ```
-    #[unstable = "the type of the argument and name of this function are \
-                      subject to change"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "the type of the argument and name of this function are \
+                         subject to change")]
     pub fn set_timeout(&mut self, ms: Option<u64>) { self.inner.set_timeout(ms); }
 
     /// Closes the accepting capabilities of this acceptor.
@@ -442,7 +447,7 @@ impl TcpAcceptor {
     /// // Signal our accept loop to exit
     /// assert!(a.close_accept().is_ok());
     /// ```
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn close_accept(&mut self) -> IoResult<()> {
         self.inner.close_accept()
     }
diff --git a/src/libstd/io/net/udp.rs b/src/libstd/io/net/udp.rs
index 8cdad3f528a..a3e4eca10bc 100644
--- a/src/libstd/io/net/udp.rs
+++ b/src/libstd/io/net/udp.rs
@@ -92,13 +92,13 @@ impl UdpSocket {
     }
 
     /// Joins a multicast IP address (becomes a member of it)
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn join_multicast(&mut self, multi: IpAddr) -> IoResult<()> {
         self.inner.join_multicast(multi)
     }
 
     /// Leaves a multicast IP address (drops membership from it)
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn leave_multicast(&mut self, multi: IpAddr) -> IoResult<()> {
         self.inner.leave_multicast(multi)
     }
@@ -106,25 +106,25 @@ impl UdpSocket {
     /// Set the multicast loop flag to the specified value
     ///
     /// This lets multicast packets loop back to local sockets (if enabled)
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn set_multicast_loop(&mut self, on: bool) -> IoResult<()> {
         self.inner.set_multicast_loop(on)
     }
 
     /// Sets the multicast TTL
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn set_multicast_ttl(&mut self, ttl: int) -> IoResult<()> {
         self.inner.multicast_time_to_live(ttl)
     }
 
     /// Sets this socket's TTL
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn set_ttl(&mut self, ttl: int) -> IoResult<()> {
         self.inner.time_to_live(ttl)
     }
 
     /// Sets the broadcast flag on or off
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn set_broadcast(&mut self, broadcast: bool) -> IoResult<()> {
         self.inner.set_broadcast(broadcast)
     }
@@ -132,7 +132,8 @@ impl UdpSocket {
     /// Sets the read/write timeout for this socket.
     ///
     /// For more information, see `TcpStream::set_timeout`
-    #[unstable = "the timeout argument may change in type and value"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "the timeout argument may change in type and value")]
     pub fn set_timeout(&mut self, timeout_ms: Option<u64>) {
         self.inner.set_timeout(timeout_ms)
     }
@@ -140,7 +141,8 @@ impl UdpSocket {
     /// Sets the read timeout for this socket.
     ///
     /// For more information, see `TcpStream::set_timeout`
-    #[unstable = "the timeout argument may change in type and value"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "the timeout argument may change in type and value")]
     pub fn set_read_timeout(&mut self, timeout_ms: Option<u64>) {
         self.inner.set_read_timeout(timeout_ms)
     }
@@ -148,7 +150,8 @@ impl UdpSocket {
     /// Sets the write timeout for this socket.
     ///
     /// For more information, see `TcpStream::set_timeout`
-    #[unstable = "the timeout argument may change in type and value"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "the timeout argument may change in type and value")]
     pub fn set_write_timeout(&mut self, timeout_ms: Option<u64>) {
         self.inner.set_write_timeout(timeout_ms)
     }
diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs
index 43ca7b13145..4762719a04e 100644
--- a/src/libstd/io/process.rs
+++ b/src/libstd/io/process.rs
@@ -691,7 +691,8 @@ impl Process {
     ///     p.wait()
     /// }
     /// ```
-    #[unstable = "the type of the timeout is likely to change"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "the type of the timeout is likely to change")]
     pub fn set_timeout(&mut self, timeout_ms: Option<u64>) {
         self.deadline = timeout_ms.map(|i| i + sys::timer::now()).unwrap_or(0);
     }
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 648326eee99..a86a6eb4bfe 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -95,7 +95,7 @@
 //! and `format!`, also available to all Rust code.
 
 #![crate_name = "std"]
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 #![staged_api]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
@@ -175,7 +175,7 @@ pub use alloc::rc;
 pub use core_collections::slice;
 pub use core_collections::str;
 pub use core_collections::string;
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub use core_collections::vec;
 
 pub use unicode::char;
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 8a8d14c4f3a..16d11077080 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -14,7 +14,7 @@
 //! library. Each macro is available for use when linking against the standard
 //! library.
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 
 /// The entry point for panic of Rust tasks.
 ///
@@ -36,7 +36,7 @@
 /// panic!("this is a {} {message}", "fancy", message = "message");
 /// ```
 #[macro_export]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 macro_rules! panic {
     () => ({
         panic!("explicit panic")
@@ -71,7 +71,7 @@ macro_rules! panic {
 /// format!("x = {}, y = {y}", 10i, y = 30i);
 /// ```
 #[macro_export]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 macro_rules! format {
     ($($arg:tt)*) => ($crate::fmt::format(format_args!($($arg)*)))
 }
@@ -79,7 +79,7 @@ macro_rules! format {
 /// Equivalent to the `println!` macro except that a newline is not printed at
 /// the end of the message.
 #[macro_export]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 macro_rules! print {
     ($($arg:tt)*) => ($crate::io::stdio::print_args(format_args!($($arg)*)))
 }
@@ -97,7 +97,7 @@ macro_rules! print {
 /// println!("format {} arguments", "some");
 /// ```
 #[macro_export]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 macro_rules! println {
     ($($arg:tt)*) => ($crate::io::stdio::println_args(format_args!($($arg)*)))
 }
@@ -106,7 +106,7 @@ macro_rules! println {
 /// error if the value of the expression is `Err`. For more information, see
 /// `std::io`.
 #[macro_export]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 macro_rules! try {
     ($expr:expr) => (match $expr {
         $crate::result::Result::Ok(val) => val,
@@ -148,7 +148,7 @@ macro_rules! try {
 ///
 /// For more information about select, see the `std::sync::mpsc::Select` structure.
 #[macro_export]
-#[unstable]
+#[unstable(feature = "unnamed_feature", since = "1.0.0")]
 macro_rules! select {
     (
         $($name:pat = $rx:ident.$meth:ident() => $code:expr),+
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs
index adbce893887..a9e40e96332 100644
--- a/src/libstd/num/f32.rs
+++ b/src/libstd/num/f32.rs
@@ -10,7 +10,7 @@
 
 //! Operations and constants for 32-bits floats (`f32` type)
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 #![allow(missing_docs)]
 #![allow(unsigned_negation)]
 #![doc(primitive = "f32")]
@@ -73,7 +73,7 @@ mod cmath {
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl Float for f32 {
     #[inline]
     fn nan() -> f32 { num::Float::nan() }
@@ -366,7 +366,7 @@ impl Float for f32 {
 ///
 /// * num - The float value
 #[inline]
-#[unstable = "may be removed or relocated"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be removed or relocated")]
 pub fn to_string(num: f32) -> String {
     let (r, _) = strconv::float_to_str_common(
         num, 10u, true, SignNeg, DigAll, ExpNone, false);
@@ -379,7 +379,7 @@ pub fn to_string(num: f32) -> String {
 ///
 /// * num - The float value
 #[inline]
-#[unstable = "may be removed or relocated"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be removed or relocated")]
 pub fn to_str_hex(num: f32) -> String {
     let (r, _) = strconv::float_to_str_common(
         num, 16u, true, SignNeg, DigAll, ExpNone, false);
@@ -394,7 +394,7 @@ pub fn to_str_hex(num: f32) -> String {
 /// * num - The float value
 /// * radix - The base to use
 #[inline]
-#[unstable = "may be removed or relocated"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be removed or relocated")]
 pub fn to_str_radix_special(num: f32, rdx: uint) -> (String, bool) {
     strconv::float_to_str_common(num, rdx, true, SignNeg, DigAll, ExpNone, false)
 }
@@ -407,7 +407,7 @@ pub fn to_str_radix_special(num: f32, rdx: uint) -> (String, bool) {
 /// * num - The float value
 /// * digits - The number of significant digits
 #[inline]
-#[unstable = "may be removed or relocated"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be removed or relocated")]
 pub fn to_str_exact(num: f32, dig: uint) -> String {
     let (r, _) = strconv::float_to_str_common(
         num, 10u, true, SignNeg, DigExact(dig), ExpNone, false);
@@ -422,7 +422,7 @@ pub fn to_str_exact(num: f32, dig: uint) -> String {
 /// * num - The float value
 /// * digits - The number of significant digits
 #[inline]
-#[unstable = "may be removed or relocated"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be removed or relocated")]
 pub fn to_str_digits(num: f32, dig: uint) -> String {
     let (r, _) = strconv::float_to_str_common(
         num, 10u, true, SignNeg, DigMax(dig), ExpNone, false);
@@ -438,7 +438,7 @@ pub fn to_str_digits(num: f32, dig: uint) -> String {
 /// * digits - The number of digits after the decimal point
 /// * upper - Use `E` instead of `e` for the exponent sign
 #[inline]
-#[unstable = "may be removed or relocated"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be removed or relocated")]
 pub fn to_str_exp_exact(num: f32, dig: uint, upper: bool) -> String {
     let (r, _) = strconv::float_to_str_common(
         num, 10u, true, SignNeg, DigExact(dig), ExpDec, upper);
@@ -454,7 +454,7 @@ pub fn to_str_exp_exact(num: f32, dig: uint, upper: bool) -> String {
 /// * digits - The number of digits after the decimal point
 /// * upper - Use `E` instead of `e` for the exponent sign
 #[inline]
-#[unstable = "may be removed or relocated"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be removed or relocated")]
 pub fn to_str_exp_digits(num: f32, dig: uint, upper: bool) -> String {
     let (r, _) = strconv::float_to_str_common(
         num, 10u, true, SignNeg, DigMax(dig), ExpDec, upper);
diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs
index baff14125ee..ae5db0b1fd8 100644
--- a/src/libstd/num/f64.rs
+++ b/src/libstd/num/f64.rs
@@ -10,7 +10,7 @@
 
 //! Operations and constants for 64-bits floats (`f64` type)
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 #![allow(missing_docs)]
 #![doc(primitive = "f64")]
 
@@ -81,7 +81,7 @@ mod cmath {
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl Float for f64 {
     // inlined methods from `num::Float`
     #[inline]
@@ -375,7 +375,7 @@ impl Float for f64 {
 ///
 /// * num - The float value
 #[inline]
-#[unstable = "may be removed or relocated"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be removed or relocated")]
 pub fn to_string(num: f64) -> String {
     let (r, _) = strconv::float_to_str_common(
         num, 10u, true, SignNeg, DigAll, ExpNone, false);
@@ -388,7 +388,7 @@ pub fn to_string(num: f64) -> String {
 ///
 /// * num - The float value
 #[inline]
-#[unstable = "may be removed or relocated"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be removed or relocated")]
 pub fn to_str_hex(num: f64) -> String {
     let (r, _) = strconv::float_to_str_common(
         num, 16u, true, SignNeg, DigAll, ExpNone, false);
@@ -403,7 +403,7 @@ pub fn to_str_hex(num: f64) -> String {
 /// * num - The float value
 /// * radix - The base to use
 #[inline]
-#[unstable = "may be removed or relocated"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be removed or relocated")]
 pub fn to_str_radix_special(num: f64, rdx: uint) -> (String, bool) {
     strconv::float_to_str_common(num, rdx, true, SignNeg, DigAll, ExpNone, false)
 }
@@ -416,7 +416,7 @@ pub fn to_str_radix_special(num: f64, rdx: uint) -> (String, bool) {
 /// * num - The float value
 /// * digits - The number of significant digits
 #[inline]
-#[unstable = "may be removed or relocated"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be removed or relocated")]
 pub fn to_str_exact(num: f64, dig: uint) -> String {
     let (r, _) = strconv::float_to_str_common(
         num, 10u, true, SignNeg, DigExact(dig), ExpNone, false);
@@ -431,7 +431,7 @@ pub fn to_str_exact(num: f64, dig: uint) -> String {
 /// * num - The float value
 /// * digits - The number of significant digits
 #[inline]
-#[unstable = "may be removed or relocated"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be removed or relocated")]
 pub fn to_str_digits(num: f64, dig: uint) -> String {
     let (r, _) = strconv::float_to_str_common(
         num, 10u, true, SignNeg, DigMax(dig), ExpNone, false);
@@ -447,7 +447,7 @@ pub fn to_str_digits(num: f64, dig: uint) -> String {
 /// * digits - The number of digits after the decimal point
 /// * upper - Use `E` instead of `e` for the exponent sign
 #[inline]
-#[unstable = "may be removed or relocated"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be removed or relocated")]
 pub fn to_str_exp_exact(num: f64, dig: uint, upper: bool) -> String {
     let (r, _) = strconv::float_to_str_common(
         num, 10u, true, SignNeg, DigExact(dig), ExpDec, upper);
@@ -463,7 +463,7 @@ pub fn to_str_exp_exact(num: f64, dig: uint, upper: bool) -> String {
 /// * digits - The number of digits after the decimal point
 /// * upper - Use `E` instead of `e` for the exponent sign
 #[inline]
-#[unstable = "may be removed or relocated"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be removed or relocated")]
 pub fn to_str_exp_digits(num: f64, dig: uint, upper: bool) -> String {
     let (r, _) = strconv::float_to_str_common(
         num, 10u, true, SignNeg, DigMax(dig), ExpDec, upper);
diff --git a/src/libstd/num/float_macros.rs b/src/libstd/num/float_macros.rs
index ec168eaaa9d..38bb62d2414 100644
--- a/src/libstd/num/float_macros.rs
+++ b/src/libstd/num/float_macros.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 #![doc(hidden)]
 
 macro_rules! assert_approx_eq {
diff --git a/src/libstd/num/i16.rs b/src/libstd/num/i16.rs
index 367147b84be..cd4e41432af 100644
--- a/src/libstd/num/i16.rs
+++ b/src/libstd/num/i16.rs
@@ -10,7 +10,7 @@
 
 //! Operations and constants for signed 16-bits integers (`i16` type)
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 #![doc(primitive = "i16")]
 
 pub use core::i16::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/i32.rs b/src/libstd/num/i32.rs
index 19fb40c9644..89f3ab81c94 100644
--- a/src/libstd/num/i32.rs
+++ b/src/libstd/num/i32.rs
@@ -10,7 +10,7 @@
 
 //! Operations and constants for signed 32-bits integers (`i32` type)
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 #![doc(primitive = "i32")]
 
 pub use core::i32::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/i64.rs b/src/libstd/num/i64.rs
index 2379b03c64f..6c866382ed3 100644
--- a/src/libstd/num/i64.rs
+++ b/src/libstd/num/i64.rs
@@ -10,7 +10,7 @@
 
 //! Operations and constants for signed 64-bits integers (`i64` type)
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 #![doc(primitive = "i64")]
 
 pub use core::i64::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/i8.rs b/src/libstd/num/i8.rs
index a09ceefc6a0..521b24cdf73 100644
--- a/src/libstd/num/i8.rs
+++ b/src/libstd/num/i8.rs
@@ -10,7 +10,7 @@
 
 //! Operations and constants for signed 8-bits integers (`i8` type)
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 #![doc(primitive = "i8")]
 
 pub use core::i8::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/int.rs b/src/libstd/num/int.rs
index 69439f85115..2bf9f9b025d 100644
--- a/src/libstd/num/int.rs
+++ b/src/libstd/num/int.rs
@@ -14,7 +14,7 @@
 //! alpha cycle along with the development of clearer conventions
 //! around integer types.
 
-#![deprecated = "replaced by isize"]
+#![deprecated(feature = "oldstuff", since = "1.0.0", reason = "replaced by isize")]
 
 pub use core::int::{BITS, BYTES, MIN, MAX};
 
diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs
index 5bc54152874..640d814c046 100644
--- a/src/libstd/num/int_macros.rs
+++ b/src/libstd/num/int_macros.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 #![doc(hidden)]
 
 macro_rules! int_module { ($T:ty) => (
diff --git a/src/libstd/num/isize.rs b/src/libstd/num/isize.rs
index 22395a1c0ff..c0ae4d6a2cd 100644
--- a/src/libstd/num/isize.rs
+++ b/src/libstd/num/isize.rs
@@ -14,7 +14,7 @@
 //! new type will gradually take place over the alpha cycle along with
 //! the development of clearer conventions around integer types.
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 #![doc(primitive = "isize")]
 
 pub use core::isize::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs
index 3432767d6cd..82363a8e169 100644
--- a/src/libstd/num/mod.rs
+++ b/src/libstd/num/mod.rs
@@ -13,7 +13,7 @@
 //! These are implemented for the primitive numeric types in `std::{u8, u16,
 //! u32, u64, uint, i8, i16, i32, i64, int, f32, f64}`.
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 #![allow(missing_docs)]
 
 #[cfg(test)] use fmt::Show;
@@ -33,11 +33,11 @@ pub use core::num::{FpCategory};
 
 use option::Option;
 
-#[unstable = "may be removed or relocated"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be removed or relocated")]
 pub mod strconv;
 
 /// Mathematical operations on primitive floating point numbers.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub trait Float
     : Copy + Clone
     + NumCast
@@ -52,172 +52,193 @@ pub trait Float
 {
     // inlined methods from `num::Float`
     /// Returns the NaN value.
-    #[unstable = "unsure about its place in the world"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "unsure about its place in the world")]
     fn nan() -> Self;
     /// Returns the infinite value.
-    #[unstable = "unsure about its place in the world"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "unsure about its place in the world")]
     fn infinity() -> Self;
     /// Returns the negative infinite value.
-    #[unstable = "unsure about its place in the world"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "unsure about its place in the world")]
     fn neg_infinity() -> Self;
     /// Returns the `0` value.
-    #[unstable = "unsure about its place in the world"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "unsure about its place in the world")]
     fn zero() -> Self;
     /// Returns -0.0.
-    #[unstable = "unsure about its place in the world"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "unsure about its place in the world")]
     fn neg_zero() -> Self;
     /// Returns the `1` value.
-    #[unstable = "unsure about its place in the world"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "unsure about its place in the world")]
     fn one() -> Self;
 
     // FIXME (#5527): These should be associated constants
 
     /// Returns the number of binary digits of mantissa that this type supports.
-    #[deprecated = "use `std::f32::MANTISSA_DIGITS` or `std::f64::MANTISSA_DIGITS` as appropriate"]
+    #[deprecated(feature = "oldstuff", since = "1.0.0",
+                 reason = "use `std::f32::MANTISSA_DIGITS` or \
+                           `std::f64::MANTISSA_DIGITS` as appropriate")]
     fn mantissa_digits(unused_self: Option<Self>) -> uint;
     /// Returns the number of base-10 digits of precision that this type supports.
-    #[deprecated = "use `std::f32::DIGITS` or `std::f64::DIGITS` as appropriate"]
+    #[deprecated(feature = "oldstuff", since = "1.0.0",
+                 reason = "use `std::f32::DIGITS` or `std::f64::DIGITS` as appropriate")]
     fn digits(unused_self: Option<Self>) -> uint;
     /// Returns the difference between 1.0 and the smallest representable number larger than 1.0.
-    #[deprecated = "use `std::f32::EPSILON` or `std::f64::EPSILON` as appropriate"]
+    #[deprecated(feature = "oldstuff", since = "1.0.0",
+                 reason = "use `std::f32::EPSILON` or `std::f64::EPSILON` as appropriate")]
     fn epsilon() -> Self;
     /// Returns the minimum binary exponent that this type can represent.
-    #[deprecated = "use `std::f32::MIN_EXP` or `std::f64::MIN_EXP` as appropriate"]
+    #[deprecated(feature = "oldstuff", since = "1.0.0",
+                 reason = "use `std::f32::MIN_EXP` or `std::f64::MIN_EXP` as appropriate")]
     fn min_exp(unused_self: Option<Self>) -> int;
     /// Returns the maximum binary exponent that this type can represent.
-    #[deprecated = "use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` as appropriate"]
+    #[deprecated(feature = "oldstuff", since = "1.0.0",
+                 reason = "use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` as appropriate")]
     fn max_exp(unused_self: Option<Self>) -> int;
     /// Returns the minimum base-10 exponent that this type can represent.
-    #[deprecated = "use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` as appropriate"]
+    #[deprecated(feature = "oldstuff", since = "1.0.0",
+                 reason = "use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` as appropriate")]
     fn min_10_exp(unused_self: Option<Self>) -> int;
     /// Returns the maximum base-10 exponent that this type can represent.
-    #[deprecated = "use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` as appropriate"]
+    #[deprecated(feature = "oldstuff", since = "1.0.0",
+                 reason = "use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` as appropriate")]
     fn max_10_exp(unused_self: Option<Self>) -> int;
 
     /// Returns the smallest finite value that this type can represent.
-    #[unstable = "unsure about its place in the world"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "unsure about its place in the world")]
     fn min_value() -> Self;
     /// Returns the smallest normalized positive number that this type can represent.
-    #[unstable = "unsure about its place in the world"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "unsure about its place in the world")]
     fn min_pos_value(unused_self: Option<Self>) -> Self;
     /// Returns the largest finite value that this type can represent.
-    #[unstable = "unsure about its place in the world"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "unsure about its place in the world")]
     fn max_value() -> Self;
 
     /// Returns true if this value is NaN and false otherwise.
-    #[unstable = "position is undecided"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "position is undecided")]
     fn is_nan(self) -> bool;
     /// Returns true if this value is positive infinity or negative infinity and
     /// false otherwise.
-    #[unstable = "position is undecided"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "position is undecided")]
     fn is_infinite(self) -> bool;
     /// Returns true if this number is neither infinite nor NaN.
-    #[unstable = "position is undecided"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "position is undecided")]
     fn is_finite(self) -> bool;
     /// Returns true if this number is neither zero, infinite, denormal, or NaN.
-    #[unstable = "position is undecided"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "position is undecided")]
     fn is_normal(self) -> bool;
     /// Returns the category that this number falls into.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn classify(self) -> FpCategory;
 
     /// Returns the mantissa, exponent and sign as integers, respectively.
-    #[unstable = "signature is undecided"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "signature is undecided")]
     fn integer_decode(self) -> (u64, i16, i8);
 
     /// Return the largest integer less than or equal to a number.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn floor(self) -> Self;
     /// Return the smallest integer greater than or equal to a number.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn ceil(self) -> Self;
     /// Return the nearest integer to a number. Round half-way cases away from
     /// `0.0`.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn round(self) -> Self;
     /// Return the integer part of a number.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn trunc(self) -> Self;
     /// Return the fractional part of a number.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn fract(self) -> Self;
 
     /// Computes the absolute value of `self`. Returns `Float::nan()` if the
     /// number is `Float::nan()`.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn abs(self) -> Self;
     /// Returns a number that represents the sign of `self`.
     ///
     /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()`
     /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()`
     /// - `Float::nan()` if the number is `Float::nan()`
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn signum(self) -> Self;
     /// Returns `true` if `self` is positive, including `+0.0` and
     /// `Float::infinity()`.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn is_positive(self) -> bool;
     /// Returns `true` if `self` is negative, including `-0.0` and
     /// `Float::neg_infinity()`.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn is_negative(self) -> bool;
 
     /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
     /// error. This produces a more accurate result with better performance than
     /// a separate multiplication operation followed by an add.
-    #[unstable = "unsure about its place in the world"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "unsure about its place in the world")]
     fn mul_add(self, a: Self, b: Self) -> Self;
     /// Take the reciprocal (inverse) of a number, `1/x`.
-    #[unstable = "unsure about its place in the world"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "unsure about its place in the world")]
     fn recip(self) -> Self;
 
     /// Raise a number to an integer power.
     ///
     /// Using this function is generally faster than using `powf`
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn powi(self, n: i32) -> Self;
     /// Raise a number to a floating point power.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn powf(self, n: Self) -> Self;
 
     /// Take the square root of a number.
     ///
     /// Returns NaN if `self` is a negative number.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn sqrt(self) -> Self;
     /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
-    #[unstable = "unsure about its place in the world"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "unsure about its place in the world")]
     fn rsqrt(self) -> Self;
 
     /// Returns `e^(self)`, (the exponential function).
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn exp(self) -> Self;
     /// Returns 2 raised to the power of the number, `2^(self)`.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn exp2(self) -> Self;
     /// Returns the natural logarithm of the number.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn ln(self) -> Self;
     /// Returns the logarithm of the number with respect to an arbitrary base.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn log(self, base: Self) -> Self;
     /// Returns the base 2 logarithm of the number.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn log2(self) -> Self;
     /// Returns the base 10 logarithm of the number.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn log10(self) -> Self;
 
     /// Convert radians to degrees.
-    #[unstable = "desirability is unclear"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "desirability is unclear")]
     fn to_degrees(self) -> Self;
     /// Convert degrees to radians.
-    #[unstable = "desirability is unclear"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "desirability is unclear")]
     fn to_radians(self) -> Self;
 
     /// Constructs a floating point number created by multiplying `x` by 2
     /// raised to the power of `exp`.
-    #[unstable = "pending integer conventions"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "pending integer conventions")]
     fn ldexp(x: Self, exp: int) -> Self;
     /// Breaks the number into a normalized fraction and a base-2 exponent,
     /// satisfying:
@@ -225,94 +246,97 @@ pub trait Float
     ///  * `self = x * pow(2, exp)`
     ///
     ///  * `0.5 <= abs(x) < 1.0`
-    #[unstable = "pending integer conventions"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "pending integer conventions")]
     fn frexp(self) -> (Self, int);
 
     /// Returns the next representable floating-point value in the direction of
     /// `other`.
-    #[unstable = "unsure about its place in the world"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "unsure about its place in the world")]
     fn next_after(self, other: Self) -> Self;
 
     /// Returns the maximum of the two numbers.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn max(self, other: Self) -> Self;
     /// Returns the minimum of the two numbers.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn min(self, other: Self) -> Self;
 
     /// The positive difference of two numbers. Returns `0.0` if the number is
     /// less than or equal to `other`, otherwise the difference between`self`
     /// and `other` is returned.
-    #[unstable = "may be renamed"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be renamed")]
     fn abs_sub(self, other: Self) -> Self;
 
     /// Take the cubic root of a number.
-    #[unstable = "may be renamed"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be renamed")]
     fn cbrt(self) -> Self;
     /// Calculate the length of the hypotenuse of a right-angle triangle given
     /// legs of length `x` and `y`.
-    #[unstable = "unsure about its place in the world"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "unsure about its place in the world")]
     fn hypot(self, other: Self) -> Self;
 
     /// Computes the sine of a number (in radians).
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn sin(self) -> Self;
     /// Computes the cosine of a number (in radians).
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn cos(self) -> Self;
     /// Computes the tangent of a number (in radians).
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn tan(self) -> Self;
 
     /// Computes the arcsine of a number. Return value is in radians in
     /// the range [-pi/2, pi/2] or NaN if the number is outside the range
     /// [-1, 1].
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn asin(self) -> Self;
     /// Computes the arccosine of a number. Return value is in radians in
     /// the range [0, pi] or NaN if the number is outside the range
     /// [-1, 1].
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn acos(self) -> Self;
     /// Computes the arctangent of a number. Return value is in radians in the
     /// range [-pi/2, pi/2];
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn atan(self) -> Self;
     /// Computes the four quadrant arctangent of a number, `y`, and another
     /// number `x`. Return value is in radians in the range [-pi, pi].
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn atan2(self, other: Self) -> Self;
     /// Simultaneously computes the sine and cosine of the number, `x`. Returns
     /// `(sin(x), cos(x))`.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn sin_cos(self) -> (Self, Self);
 
     /// Returns the exponential of the number, minus 1, in a way that is
     /// accurate even if the number is close to zero.
-    #[unstable = "may be renamed"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be renamed")]
     fn exp_m1(self) -> Self;
     /// Returns the natural logarithm of the number plus 1 (`ln(1+n)`) more
     /// accurately than if the operations were performed separately.
-    #[unstable = "may be renamed"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "may be renamed")]
     fn ln_1p(self) -> Self;
 
     /// Hyperbolic sine function.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn sinh(self) -> Self;
     /// Hyperbolic cosine function.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn cosh(self) -> Self;
     /// Hyperbolic tangent function.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn tanh(self) -> Self;
     /// Inverse hyperbolic sine function.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn asinh(self) -> Self;
     /// Inverse hyperbolic cosine function.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn acosh(self) -> Self;
     /// Inverse hyperbolic tangent function.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     fn atanh(self) -> Self;
 }
 
diff --git a/src/libstd/num/u16.rs b/src/libstd/num/u16.rs
index 7cb6a8ffe07..06773a37ab5 100644
--- a/src/libstd/num/u16.rs
+++ b/src/libstd/num/u16.rs
@@ -10,7 +10,7 @@
 
 //! Operations and constants for unsigned 16-bits integers (`u16` type)
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 #![doc(primitive = "u16")]
 
 pub use core::u16::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/u32.rs b/src/libstd/num/u32.rs
index 43b01ddb16b..a58941b00f9 100644
--- a/src/libstd/num/u32.rs
+++ b/src/libstd/num/u32.rs
@@ -10,7 +10,7 @@
 
 //! Operations and constants for unsigned 32-bits integers (`u32` type)
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 #![doc(primitive = "u32")]
 
 pub use core::u32::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/u64.rs b/src/libstd/num/u64.rs
index 79e7f237051..2a42382dd8f 100644
--- a/src/libstd/num/u64.rs
+++ b/src/libstd/num/u64.rs
@@ -10,7 +10,7 @@
 
 //! Operations and constants for unsigned 64-bits integer (`u64` type)
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 #![doc(primitive = "u64")]
 
 pub use core::u64::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/u8.rs b/src/libstd/num/u8.rs
index 3da2fabe3f2..952c8c0347f 100644
--- a/src/libstd/num/u8.rs
+++ b/src/libstd/num/u8.rs
@@ -10,7 +10,7 @@
 
 //! Operations and constants for unsigned 8-bits integers (`u8` type)
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 #![doc(primitive = "u8")]
 
 pub use core::u8::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs
index 0e12eff205f..58685b05981 100644
--- a/src/libstd/num/uint.rs
+++ b/src/libstd/num/uint.rs
@@ -14,7 +14,7 @@
 //! alpha cycle along with the development of clearer conventions
 //! around integer types.
 
-#![deprecated = "replaced by usize"]
+#![deprecated(feature = "oldstuff", since = "1.0.0", reason = "replaced by usize")]
 
 pub use core::uint::{BITS, BYTES, MIN, MAX};
 
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index f480a3b420f..786912f0028 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 #![doc(hidden)]
 #![allow(unsigned_negation)]
 
diff --git a/src/libstd/num/usize.rs b/src/libstd/num/usize.rs
index 74dd38e13c5..52601a92ed4 100644
--- a/src/libstd/num/usize.rs
+++ b/src/libstd/num/usize.rs
@@ -14,7 +14,7 @@
 //! new type will gradually take place over the alpha cycle along with
 //! the development of clearer conventions around integer types.
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 #![doc(primitive = "usize")]
 
 pub use core::usize::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 78db6c158a8..2b5748604d1 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -22,7 +22,7 @@
 //! so we will not _hide_ the facts of which OS the user is on -- they should be given the
 //! opportunity to write OS-ignorant code by default.
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 
 #![allow(missing_docs)]
 #![allow(non_snake_case)]
diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs
index 541f1e77140..2a21f449551 100644
--- a/src/libstd/path/mod.rs
+++ b/src/libstd/path/mod.rs
@@ -59,7 +59,7 @@
 //! println!("path exists: {}", path.exists());
 //! ```
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 
 use core::marker::Sized;
 use ffi::CString;
diff --git a/src/libstd/prelude/mod.rs b/src/libstd/prelude/mod.rs
index 0496944dbaf..7e53f45422d 100644
--- a/src/libstd/prelude/mod.rs
+++ b/src/libstd/prelude/mod.rs
@@ -35,7 +35,7 @@
 //! pervasive that it would be obnoxious to import for every use, particularly
 //! those that define methods on primitive types.
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub mod v1;
diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs
index d9c942c0185..e0302c54a5a 100644
--- a/src/libstd/prelude/v1.rs
+++ b/src/libstd/prelude/v1.rs
@@ -10,35 +10,54 @@
 
 //! The first version of the prelude of the standard library.
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 
 // Reexported core operators
-#[stable] #[doc(no_inline)] pub use marker::{Copy, Send, Sized, Sync};
-#[stable] #[doc(no_inline)] pub use ops::{Drop, Fn, FnMut, FnOnce};
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use marker::{Copy, Send, Sized, Sync};
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use ops::{Drop, Fn, FnMut, FnOnce};
 
 // TEMPORARY
-#[unstable] #[doc(no_inline)] pub use ops::FullRange;
+#[unstable(feature = "unnamed_feature", since = "1.0.0")]
+#[doc(no_inline)] pub use ops::FullRange;
 
 // Reexported functions
-#[stable] #[doc(no_inline)] pub use mem::drop;
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use mem::drop;
 
 // Reexported types and traits
 
-#[stable] #[doc(no_inline)] pub use boxed::Box;
-#[stable] #[doc(no_inline)] pub use char::CharExt;
-#[stable] #[doc(no_inline)] pub use clone::Clone;
-#[stable] #[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
-#[stable] #[doc(no_inline)] pub use iter::DoubleEndedIterator;
-#[stable] #[doc(no_inline)] pub use iter::ExactSizeIterator;
-#[stable] #[doc(no_inline)] pub use iter::{Iterator, IteratorExt, Extend};
-#[stable] #[doc(no_inline)] pub use option::Option::{self, Some, None};
-#[stable] #[doc(no_inline)] pub use ptr::{PtrExt, MutPtrExt};
-#[stable] #[doc(no_inline)] pub use result::Result::{self, Ok, Err};
-#[stable] #[doc(no_inline)] pub use slice::AsSlice;
-#[stable] #[doc(no_inline)] pub use slice::{SliceExt, SliceConcatExt};
-#[stable] #[doc(no_inline)] pub use str::{Str, StrExt};
-#[stable] #[doc(no_inline)] pub use string::{String, ToString};
-#[stable] #[doc(no_inline)] pub use vec::Vec;
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use boxed::Box;
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use char::CharExt;
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use clone::Clone;
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use iter::DoubleEndedIterator;
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use iter::ExactSizeIterator;
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use iter::{Iterator, IteratorExt, Extend};
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use option::Option::{self, Some, None};
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use ptr::{PtrExt, MutPtrExt};
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use result::Result::{self, Ok, Err};
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use slice::AsSlice;
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use slice::{SliceExt, SliceConcatExt};
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use str::{Str, StrExt};
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use string::{String, ToString};
+#[stable(feature = "grandfathered", since = "1.0.0")]
+#[doc(no_inline)] pub use vec::Vec;
 
 // NB: remove when path reform lands
 #[doc(no_inline)] pub use path::{Path, GenericPath};
diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs
index 23387d29553..24969ddb01c 100644
--- a/src/libstd/rand/mod.rs
+++ b/src/libstd/rand/mod.rs
@@ -219,7 +219,7 @@
 //! }
 //! ```
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 
 use cell::RefCell;
 use clone::Clone;
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index e3e4e132b81..b4cc27ce926 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -16,7 +16,7 @@
 //! and should be considered as private implementation details for the
 //! time being.
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 
 // FIXME: this should not be here.
 #![allow(missing_docs)]
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
index 73b8f104c23..1d8c7cd5910 100644
--- a/src/libstd/rt/unwind.rs
+++ b/src/libstd/rt/unwind.rs
@@ -582,7 +582,7 @@ fn begin_unwind_inner(msg: Box<Any + Send>, file_line: &(&'static str, uint)) ->
 /// Only a limited number of callbacks can be registered, and this function
 /// returns whether the callback was successfully registered or not. It is not
 /// currently possible to unregister a callback once it has been registered.
-#[unstable]
+#[unstable(feature = "unnamed_feature", since = "1.0.0")]
 pub unsafe fn register(f: Callback) -> bool {
     match CALLBACK_CNT.fetch_add(1, Ordering::SeqCst) {
         // The invocation code has knowledge of this window where the count has
diff --git a/src/libstd/rtdeps.rs b/src/libstd/rtdeps.rs
index f4fbd378899..4a178c7d384 100644
--- a/src/libstd/rtdeps.rs
+++ b/src/libstd/rtdeps.rs
@@ -12,7 +12,7 @@
 //! the standard library This varies per-platform, but these libraries are
 //! necessary for running libstd.
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 
 // All platforms need to link to rustrt
 #[cfg(not(test))]
diff --git a/src/libstd/sync/barrier.rs b/src/libstd/sync/barrier.rs
index 70939879400..c65a772da04 100644
--- a/src/libstd/sync/barrier.rs
+++ b/src/libstd/sync/barrier.rs
@@ -29,7 +29,7 @@ use sync::{Mutex, Condvar};
 ///     });
 /// }
 /// ```
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Barrier {
     lock: Mutex<BarrierState>,
     cvar: Condvar,
@@ -54,7 +54,7 @@ impl Barrier {
     ///
     /// A barrier will block `n`-1 threads which call `wait` and then wake up
     /// all threads at once when the `n`th thread calls `wait`.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn new(n: uint) -> Barrier {
         Barrier {
             lock: Mutex::new(BarrierState {
@@ -75,7 +75,7 @@ impl Barrier {
     /// returns `true` from `is_leader` when returning from this function, and
     /// all other threads will receive a result that will return `false` from
     /// `is_leader`
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn wait(&self) -> BarrierWaitResult {
         let mut lock = self.lock.lock().unwrap();
         let local_gen = lock.generation_id;
@@ -102,7 +102,7 @@ impl BarrierWaitResult {
     ///
     /// Only one thread will have `true` returned from their result, all other
     /// threads will have `false` returned.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn is_leader(&self) -> bool { self.0 }
 }
 
diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs
index d2d5335078e..739e70720ca 100644
--- a/src/libstd/sync/condvar.rs
+++ b/src/libstd/sync/condvar.rs
@@ -58,7 +58,7 @@ use sync::{mutex, MutexGuard};
 ///     started = cvar.wait(started).unwrap();
 /// }
 /// ```
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Condvar { inner: Box<StaticCondvar> }
 
 unsafe impl Send for Condvar {}
@@ -76,7 +76,8 @@ unsafe impl Sync for Condvar {}
 ///
 /// static CVAR: StaticCondvar = CONDVAR_INIT;
 /// ```
-#[unstable = "may be merged with Condvar in the future"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "may be merged with Condvar in the future")]
 pub struct StaticCondvar {
     inner: sys::Condvar,
     mutex: AtomicUsize,
@@ -86,7 +87,8 @@ unsafe impl Send for StaticCondvar {}
 unsafe impl Sync for StaticCondvar {}
 
 /// Constant initializer for a statically allocated condition variable.
-#[unstable = "may be merged with Condvar in the future"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "may be merged with Condvar in the future")]
 pub const CONDVAR_INIT: StaticCondvar = StaticCondvar {
     inner: sys::CONDVAR_INIT,
     mutex: ATOMIC_USIZE_INIT,
@@ -95,7 +97,7 @@ pub const CONDVAR_INIT: StaticCondvar = StaticCondvar {
 impl Condvar {
     /// Creates a new condition variable which is ready to be waited on and
     /// notified.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn new() -> Condvar {
         Condvar {
             inner: box StaticCondvar {
@@ -131,7 +133,7 @@ impl Condvar {
     /// over time. Each condition variable is dynamically bound to exactly one
     /// mutex to ensure defined behavior across platforms. If this functionality
     /// is not desired, then unsafe primitives in `sys` are provided.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn wait<'a, T>(&self, guard: MutexGuard<'a, T>)
                        -> LockResult<MutexGuard<'a, T>> {
         unsafe {
@@ -154,7 +156,7 @@ impl Condvar {
     ///
     /// Like `wait`, the lock specified will be re-acquired when this function
     /// returns, regardless of whether the timeout elapsed or not.
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn wait_timeout<'a, T>(&self, guard: MutexGuard<'a, T>, dur: Duration)
                            -> LockResult<(MutexGuard<'a, T>, bool)> {
         unsafe {
@@ -169,7 +171,7 @@ impl Condvar {
     /// The semantics of this function are equivalent to `wait_timeout` except
     /// that the implementation will repeatedly wait while the duration has not
     /// passed and the provided function returns `false`.
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn wait_timeout_with<'a, T, F>(&self,
                                        guard: MutexGuard<'a, T>,
                                        dur: Duration,
@@ -189,7 +191,7 @@ impl Condvar {
     /// `notify_one` are not buffered in any way.
     ///
     /// To wake up all threads, see `notify_all()`.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn notify_one(&self) { unsafe { self.inner.inner.notify_one() } }
 
     /// Wake up all blocked threads on this condvar.
@@ -199,11 +201,11 @@ impl Condvar {
     /// way.
     ///
     /// To wake up only one thread, see `notify_one()`.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn notify_all(&self) { unsafe { self.inner.inner.notify_all() } }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl Drop for Condvar {
     fn drop(&mut self) {
         unsafe { self.inner.inner.destroy() }
@@ -215,7 +217,8 @@ impl StaticCondvar {
     /// notification.
     ///
     /// See `Condvar::wait`.
-    #[unstable = "may be merged with Condvar in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Condvar in the future")]
     pub fn wait<'a, T>(&'static self, guard: MutexGuard<'a, T>)
                        -> LockResult<MutexGuard<'a, T>> {
         let poisoned = unsafe {
@@ -235,7 +238,8 @@ impl StaticCondvar {
     /// specified duration.
     ///
     /// See `Condvar::wait_timeout`.
-    #[unstable = "may be merged with Condvar in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Condvar in the future")]
     pub fn wait_timeout<'a, T>(&'static self, guard: MutexGuard<'a, T>, dur: Duration)
                                -> LockResult<(MutexGuard<'a, T>, bool)> {
         let (poisoned, success) = unsafe {
@@ -258,7 +262,8 @@ impl StaticCondvar {
     /// passed and the function returns `false`.
     ///
     /// See `Condvar::wait_timeout_with`.
-    #[unstable = "may be merged with Condvar in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Condvar in the future")]
     pub fn wait_timeout_with<'a, T, F>(&'static self,
                                        guard: MutexGuard<'a, T>,
                                        dur: Duration,
@@ -298,13 +303,15 @@ impl StaticCondvar {
     /// Wake up one blocked thread on this condvar.
     ///
     /// See `Condvar::notify_one`.
-    #[unstable = "may be merged with Condvar in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Condvar in the future")]
     pub fn notify_one(&'static self) { unsafe { self.inner.notify_one() } }
 
     /// Wake up all blocked threads on this condvar.
     ///
     /// See `Condvar::notify_all`.
-    #[unstable = "may be merged with Condvar in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Condvar in the future")]
     pub fn notify_all(&'static self) { unsafe { self.inner.notify_all() } }
 
     /// Deallocate all resources associated with this static condvar.
@@ -313,7 +320,8 @@ impl StaticCondvar {
     /// active users of the condvar, and this also doesn't prevent any future
     /// users of the condvar. This method is required to be called to not leak
     /// memory on all platforms.
-    #[unstable = "may be merged with Condvar in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Condvar in the future")]
     pub unsafe fn destroy(&'static self) {
         self.inner.destroy()
     }
diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs
index 36bbc5ff5b4..bb309d5c2e8 100644
--- a/src/libstd/sync/future.rs
+++ b/src/libstd/sync/future.rs
@@ -27,9 +27,10 @@
 //! ```
 
 #![allow(missing_docs)]
-#![unstable = "futures as-is have yet to be deeply reevaluated with recent \
-               core changes to Rust's synchronization story, and will likely \
-               become stable in the future but are unstable until that time"]
+#![unstable(feature = "unnamed_feature", since = "1.0.0",
+            reason = "futures as-is have yet to be deeply reevaluated with recent \
+                      core changes to Rust's synchronization story, and will likely \
+                      become stable in the future but are unstable until that time")]
 
 use core::prelude::*;
 use core::mem::replace;
diff --git a/src/libstd/sync/mod.rs b/src/libstd/sync/mod.rs
index 6fff6765bd3..9e9d204aa46 100644
--- a/src/libstd/sync/mod.rs
+++ b/src/libstd/sync/mod.rs
@@ -15,7 +15,7 @@
 //! and/or blocking at all, but rather provide the necessary tools to build
 //! other types of concurrent primitives.
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 
 pub use alloc::arc::{Arc, Weak};
 pub use core::atomic;
diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs
index 0ba19b70617..73ddd2e4c45 100644
--- a/src/libstd/sync/mpsc/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -163,7 +163,7 @@
 //! }
 //! ```
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 
 // A description of how Rust's channel implementation works
 //
@@ -339,7 +339,7 @@ mod spsc_queue;
 
 /// The receiving-half of Rust's channel type. This half can only be owned by
 /// one task
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Receiver<T> {
     inner: UnsafeCell<Flavor<T>>,
 }
@@ -351,14 +351,14 @@ unsafe impl<T:Send> Send for Receiver<T> { }
 /// An iterator over messages on a receiver, this iterator will block
 /// whenever `next` is called, waiting for a new message, and `None` will be
 /// returned when the corresponding channel has hung up.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Iter<'a, T:'a> {
     rx: &'a Receiver<T>
 }
 
 /// The sending-half of Rust's asynchronous channel type. This half can only be
 /// owned by one task, but it can be cloned to send to other tasks.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Sender<T> {
     inner: UnsafeCell<Flavor<T>>,
 }
@@ -369,8 +369,8 @@ unsafe impl<T:Send> Send for Sender<T> { }
 
 /// The sending-half of Rust's synchronous channel type. This half can only be
 /// owned by one task, but it can be cloned to send to other tasks.
-#[stable]
 #[cfg(stage0)] // NOTE remove impl after next snapshot
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct SyncSender<T> {
     inner: Arc<RacyCell<sync::Packet<T>>>,
     // can't share in an arc
@@ -379,7 +379,7 @@ pub struct SyncSender<T> {
 
 /// The sending-half of Rust's synchronous channel type. This half can only be
 /// owned by one task, but it can be cloned to send to other tasks.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
 pub struct SyncSender<T> {
     inner: Arc<RacyCell<sync::Packet<T>>>,
@@ -394,7 +394,7 @@ impl<T> !marker::Sync for SyncSender<T> {}
 /// disconnected, implying that the data could never be received. The error
 /// contains the data being sent as a payload so it can be recovered.
 #[derive(PartialEq, Eq)]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct SendError<T>(pub T);
 
 /// An error returned from the `recv` function on a `Receiver`.
@@ -402,29 +402,29 @@ pub struct SendError<T>(pub T);
 /// The `recv` operation can only fail if the sending half of a channel is
 /// disconnected, implying that no further messages will ever be received.
 #[derive(PartialEq, Eq, Clone, Copy)]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct RecvError;
 
 /// This enumeration is the list of the possible reasons that try_recv could not
 /// return data when called.
 #[derive(PartialEq, Clone, Copy)]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub enum TryRecvError {
     /// This channel is currently empty, but the sender(s) have not yet
     /// disconnected, so data may yet become available.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     Empty,
 
     /// This channel's sending half has become disconnected, and there will
     /// never be any more data received on this channel
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     Disconnected,
 }
 
 /// This enumeration is the list of the possible error outcomes for the
 /// `SyncSender::try_send` method.
 #[derive(PartialEq, Clone)]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub enum TrySendError<T> {
     /// The data could not be sent on the channel because it would require that
     /// the callee block to send the data.
@@ -432,12 +432,12 @@ pub enum TrySendError<T> {
     /// If this is a buffered channel, then the buffer is full at this time. If
     /// this is not a buffered channel, then there is no receiver available to
     /// acquire the data.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     Full(T),
 
     /// This channel's receiving half has disconnected, so the data could not be
     /// sent. The data is returned back to the callee in this case.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     Disconnected(T),
 }
 
@@ -495,7 +495,7 @@ impl<T> UnsafeFlavor<T> for Receiver<T> {
 /// // Let's see what that answer was
 /// println!("{:?}", rx.recv().unwrap());
 /// ```
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) {
     let a = Arc::new(RacyCell::new(oneshot::Packet::new()));
     (Sender::new(Flavor::Oneshot(a.clone())), Receiver::new(Flavor::Oneshot(a)))
@@ -535,7 +535,7 @@ pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) {
 /// assert_eq!(rx.recv().unwrap(), 1i);
 /// assert_eq!(rx.recv().unwrap(), 2i);
 /// ```
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub fn sync_channel<T: Send>(bound: uint) -> (SyncSender<T>, Receiver<T>) {
     let a = Arc::new(RacyCell::new(sync::Packet::new(bound)));
     (SyncSender::new(a.clone()), Receiver::new(Flavor::Sync(a)))
@@ -579,7 +579,7 @@ impl<T: Send> Sender<T> {
     /// drop(rx);
     /// assert_eq!(tx.send(1i).err().unwrap().0, 1);
     /// ```
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn send(&self, t: T) -> Result<(), SendError<T>> {
         let (new_inner, ret) = match *unsafe { self.inner() } {
             Flavor::Oneshot(ref p) => {
@@ -626,7 +626,7 @@ impl<T: Send> Sender<T> {
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T: Send> Clone for Sender<T> {
     fn clone(&self) -> Sender<T> {
         let (packet, sleeper, guard) = match *unsafe { self.inner() } {
@@ -672,7 +672,7 @@ impl<T: Send> Clone for Sender<T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T: Send> Drop for Sender<T> {
     fn drop(&mut self) {
         match *unsafe { self.inner_mut() } {
@@ -713,7 +713,7 @@ impl<T: Send> SyncSender<T> {
     /// This function will never panic, but it may return `Err` if the
     /// `Receiver` has disconnected and is no longer able to receive
     /// information.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn send(&self, t: T) -> Result<(), SendError<T>> {
         unsafe { (*self.inner.get()).send(t).map_err(SendError) }
     }
@@ -727,13 +727,13 @@ impl<T: Send> SyncSender<T> {
     ///
     /// See `SyncSender::send` for notes about guarantees of whether the
     /// receiver has received the data or not if this function is successful.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>> {
         unsafe { (*self.inner.get()).try_send(t) }
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T: Send> Clone for SyncSender<T> {
     fn clone(&self) -> SyncSender<T> {
         unsafe { (*self.inner.get()).clone_chan(); }
@@ -742,7 +742,7 @@ impl<T: Send> Clone for SyncSender<T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T: Send> Drop for SyncSender<T> {
     fn drop(&mut self) {
         unsafe { (*self.inner.get()).drop_chan(); }
@@ -766,7 +766,7 @@ impl<T: Send> Receiver<T> {
     ///
     /// This is useful for a flavor of "optimistic check" before deciding to
     /// block on a receiver.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn try_recv(&self) -> Result<T, TryRecvError> {
         loop {
             let new_port = match *unsafe { self.inner() } {
@@ -827,7 +827,7 @@ impl<T: Send> Receiver<T> {
     /// If the corresponding `Sender` has disconnected, or it disconnects while
     /// this call is blocking, this call will wake up and return `Err` to
     /// indicate that no more messages can ever be received on this channel.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn recv(&self) -> Result<T, RecvError> {
         loop {
             let new_port = match *unsafe { self.inner() } {
@@ -866,7 +866,7 @@ impl<T: Send> Receiver<T> {
 
     /// Returns an iterator that will block waiting for messages, but never
     /// `panic!`. It will return `None` when the channel has hung up.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn iter(&self) -> Iter<T> {
         Iter { rx: self }
     }
@@ -958,7 +958,7 @@ impl<T: Send> select::Packet for Receiver<T> {
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, T: Send> Iterator for Iter<'a, T> {
     type Item = T;
 
@@ -966,7 +966,7 @@ impl<'a, T: Send> Iterator for Iter<'a, T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T: Send> Drop for Receiver<T> {
     fn drop(&mut self) {
         match *unsafe { self.inner_mut() } {
diff --git a/src/libstd/sync/mpsc/mpsc_queue.rs b/src/libstd/sync/mpsc/mpsc_queue.rs
index 83de98fdbff..9747de3b7f9 100644
--- a/src/libstd/sync/mpsc/mpsc_queue.rs
+++ b/src/libstd/sync/mpsc/mpsc_queue.rs
@@ -35,7 +35,7 @@
 //! method, and see the method for more information about it. Due to this
 //! caveat, this queue may not be appropriate for all use-cases.
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 
 // http://www.1024cores.net/home/lock-free-algorithms
 //                         /queues/non-intrusive-mpsc-node-based-queue
@@ -138,7 +138,7 @@ impl<T: Send> Queue<T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T: Send> Drop for Queue<T> {
     fn drop(&mut self) {
         unsafe {
diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs
index 62a7b823ec8..1a433db2deb 100644
--- a/src/libstd/sync/mpsc/select.rs
+++ b/src/libstd/sync/mpsc/select.rs
@@ -46,12 +46,13 @@
 //! ```
 
 #![allow(dead_code)]
-#![unstable = "This implementation, while likely sufficient, is unsafe and \
-                   likely to be error prone. At some point in the future this \
-                   module will likely be replaced, and it is currently \
-                   unknown how much API breakage that will cause. The ability \
-                   to select over a number of channels will remain forever, \
-                   but no guarantees beyond this are being made"]
+#![unstable(feature = "unnamed_feature", since = "1.0.0",
+            reason = "This implementation, while likely sufficient, is unsafe and \
+                      likely to be error prone. At some point in the future this \
+                      module will likely be replaced, and it is currently \
+                      unknown how much API breakage that will cause. The ability \
+                      to select over a number of channels will remain forever, \
+                      but no guarantees beyond this are being made")]
 
 
 use core::prelude::*;
diff --git a/src/libstd/sync/mpsc/spsc_queue.rs b/src/libstd/sync/mpsc/spsc_queue.rs
index 34fd6bb70dc..cc7a34f8d4c 100644
--- a/src/libstd/sync/mpsc/spsc_queue.rs
+++ b/src/libstd/sync/mpsc/spsc_queue.rs
@@ -33,7 +33,7 @@
 //! concurrently between two tasks. This data structure is safe to use and
 //! enforces the semantics that there is one pusher and one popper.
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 
 use core::prelude::*;
 
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index 73d5332d16f..343dfbf68c7 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -109,7 +109,7 @@ use sys_common::mutex as sys;
 ///
 /// *guard += 1;
 /// ```
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Mutex<T> {
     // Note that this static mutex is in a *box*, not inlined into the struct
     // itself. Once a native mutex has been used once, its address can never
@@ -145,7 +145,8 @@ unsafe impl<T:Send> Sync for Mutex<T> { }
 /// }
 /// // lock is unlocked here.
 /// ```
-#[unstable = "may be merged with Mutex in the future"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "may be merged with Mutex in the future")]
 pub struct StaticMutex {
     lock: sys::Mutex,
     poison: poison::Flag,
@@ -159,8 +160,8 @@ unsafe impl Sync for StaticMutex {}
 /// The data protected by the mutex can be access through this guard via its
 /// Deref and DerefMut implementations
 #[must_use]
-#[stable]
 #[cfg(stage0)] // NOTE remove impl after next snapshot
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct MutexGuard<'a, T: 'a> {
     // funny underscores due to how Deref/DerefMut currently work (they
     // disregard field privacy).
@@ -176,7 +177,7 @@ pub struct MutexGuard<'a, T: 'a> {
 /// The data protected by the mutex can be access through this guard via its
 /// Deref and DerefMut implementations
 #[must_use]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
 pub struct MutexGuard<'a, T: 'a> {
     // funny underscores due to how Deref/DerefMut currently work (they
@@ -191,7 +192,8 @@ impl<'a, T> !marker::Send for MutexGuard<'a, T> {}
 
 /// Static initialization of a mutex. This constant can be used to initialize
 /// other mutex constants.
-#[unstable = "may be merged with Mutex in the future"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "may be merged with Mutex in the future")]
 pub const MUTEX_INIT: StaticMutex = StaticMutex {
     lock: sys::MUTEX_INIT,
     poison: poison::FLAG_INIT,
@@ -199,7 +201,7 @@ pub const MUTEX_INIT: StaticMutex = StaticMutex {
 
 impl<T: Send> Mutex<T> {
     /// Creates a new mutex in an unlocked state ready for use.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn new(t: T) -> Mutex<T> {
         Mutex {
             inner: box MUTEX_INIT,
@@ -218,7 +220,7 @@ impl<T: Send> Mutex<T> {
     ///
     /// If another user of this mutex panicked while holding the mutex, then
     /// this call will return an error once the mutex is acquired.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn lock(&self) -> LockResult<MutexGuard<T>> {
         unsafe { self.inner.lock.lock() }
         MutexGuard::new(&*self.inner, &self.data)
@@ -237,7 +239,7 @@ impl<T: Send> Mutex<T> {
     /// If another user of this mutex panicked while holding the mutex, then
     /// this call will return failure if the mutex would otherwise be
     /// acquired.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn try_lock(&self) -> TryLockResult<MutexGuard<T>> {
         if unsafe { self.inner.lock.try_lock() } {
             Ok(try!(MutexGuard::new(&*self.inner, &self.data)))
@@ -248,7 +250,7 @@ impl<T: Send> Mutex<T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T: Send> Drop for Mutex<T> {
     fn drop(&mut self) {
         // This is actually safe b/c we know that there is no further usage of
@@ -265,7 +267,8 @@ static DUMMY: Dummy = Dummy(UnsafeCell { value: () });
 impl StaticMutex {
     /// Acquires this lock, see `Mutex::lock`
     #[inline]
-    #[unstable = "may be merged with Mutex in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Mutex in the future")]
     pub fn lock(&'static self) -> LockResult<MutexGuard<()>> {
         unsafe { self.lock.lock() }
         MutexGuard::new(self, &DUMMY.0)
@@ -273,7 +276,8 @@ impl StaticMutex {
 
     /// Attempts to grab this lock, see `Mutex::try_lock`
     #[inline]
-    #[unstable = "may be merged with Mutex in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Mutex in the future")]
     pub fn try_lock(&'static self) -> TryLockResult<MutexGuard<()>> {
         if unsafe { self.lock.try_lock() } {
             Ok(try!(MutexGuard::new(self, &DUMMY.0)))
@@ -292,7 +296,8 @@ impl StaticMutex {
     /// *all* platforms. It may be the case that some platforms do not leak
     /// memory if this method is not called, but this is not guaranteed to be
     /// true on all platforms.
-    #[unstable = "may be merged with Mutex in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with Mutex in the future")]
     pub unsafe fn destroy(&'static self) {
         self.lock.destroy()
     }
@@ -325,7 +330,7 @@ impl<'mutex, T> MutexGuard<'mutex, T> {
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'mutex, T> Deref for MutexGuard<'mutex, T> {
     type Target = T;
 
@@ -333,7 +338,7 @@ impl<'mutex, T> Deref for MutexGuard<'mutex, T> {
         unsafe { &*self.__data.get() }
     }
 }
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'mutex, T> DerefMut for MutexGuard<'mutex, T> {
     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
         unsafe { &mut *self.__data.get() }
@@ -341,7 +346,7 @@ impl<'mutex, T> DerefMut for MutexGuard<'mutex, T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, T> Drop for MutexGuard<'a, T> {
     #[inline]
     fn drop(&mut self) {
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index 6231a91833d..82ed62966b5 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -36,7 +36,7 @@ use sync::{StaticMutex, MUTEX_INIT};
 ///     // run initialization here
 /// });
 /// ```
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Once {
     mutex: StaticMutex,
     cnt: AtomicIsize,
@@ -46,7 +46,7 @@ pub struct Once {
 unsafe impl Sync for Once {}
 
 /// Initialization value for static `Once` values.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub const ONCE_INIT: Once = Once {
     mutex: MUTEX_INIT,
     cnt: ATOMIC_ISIZE_INIT,
@@ -63,7 +63,7 @@ impl Once {
     ///
     /// When this function returns, it is guaranteed that some initialization
     /// has run and completed (it may not be the closure specified).
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn call_once<F>(&'static self, f: F) where F: FnOnce() {
         // Optimize common path: load is much cheaper than fetch_add.
         if self.cnt.load(Ordering::SeqCst) < 0 {
diff --git a/src/libstd/sync/poison.rs b/src/libstd/sync/poison.rs
index e28c3c37b6f..4443fc2be60 100644
--- a/src/libstd/sync/poison.rs
+++ b/src/libstd/sync/poison.rs
@@ -53,22 +53,22 @@ pub struct Guard {
 /// is held. The precise semantics for when a lock is poisoned is documented on
 /// each lock, but once a lock is poisoned then all future acquisitions will
 /// return this error.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct PoisonError<T> {
     guard: T,
 }
 
 /// An enumeration of possible errors which can occur while calling the
 /// `try_lock` method.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub enum TryLockError<T> {
     /// The lock could not be acquired because another task failed while holding
     /// the lock.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     Poisoned(PoisonError<T>),
     /// The lock could not be acquired at this time because the operation would
     /// otherwise block.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     WouldBlock,
 }
 
@@ -79,7 +79,7 @@ pub enum TryLockError<T> {
 /// that the primitive was poisoned. Note that the `Err` variant *also* carries
 /// the associated guard, and it can be acquired through the `into_inner`
 /// method.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub type LockResult<Guard> = Result<Guard, PoisonError<Guard>>;
 
 /// A type alias for the result of a nonblocking locking method.
@@ -87,7 +87,7 @@ pub type LockResult<Guard> = Result<Guard, PoisonError<Guard>>;
 /// For more information, see `LockResult`. A `TryLockResult` doesn't
 /// necessarily hold the associated guard in the `Err` type as the lock may not
 /// have been acquired for other reasons.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub type TryLockResult<Guard> = Result<Guard, TryLockError<Guard>>;
 
 impl<T> fmt::Show for PoisonError<T> {
@@ -105,22 +105,22 @@ impl<T> Error for PoisonError<T> {
 impl<T> PoisonError<T> {
     /// Consumes this error indicating that a lock is poisoned, returning the
     /// underlying guard to allow access regardless.
-    #[deprecated="renamed to into_inner"]
+    #[deprecated(feature = "oldstuff", since = "1.0.0", reason = "renamed to into_inner")]
     pub fn into_guard(self) -> T { self.guard }
 
     /// Consumes this error indicating that a lock is poisoned, returning the
     /// underlying guard to allow access regardless.
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn into_inner(self) -> T { self.guard }
 
     /// Reaches into this error indicating that a lock is poisoned, returning a
     /// reference to the underlying guard to allow access regardless.
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn get_ref(&self) -> &T { &self.guard }
 
     /// Reaches into this error indicating that a lock is poisoned, returning a
     /// mutable reference to the underlying guard to allow access regardless.
-    #[unstable]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut T { &mut self.guard }
 }
 
diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs
index 237f6d08a95..6d0b34b3c87 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -58,7 +58,7 @@ use sys_common::rwlock as sys;
 ///     assert_eq!(*w, 6);
 /// } // write lock is dropped here
 /// ```
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct RwLock<T> {
     inner: Box<StaticRwLock>,
     data: UnsafeCell<T>,
@@ -90,7 +90,8 @@ unsafe impl<T> Sync for RwLock<T> {}
 /// }
 /// unsafe { LOCK.destroy() } // free all resources
 /// ```
-#[unstable = "may be merged with RwLock in the future"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "may be merged with RwLock in the future")]
 pub struct StaticRwLock {
     lock: sys::RWLock,
     poison: poison::Flag,
@@ -100,7 +101,8 @@ unsafe impl Send for StaticRwLock {}
 unsafe impl Sync for StaticRwLock {}
 
 /// Constant initialization for a statically-initialized rwlock.
-#[unstable = "may be merged with RwLock in the future"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "may be merged with RwLock in the future")]
 pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock {
     lock: sys::RWLOCK_INIT,
     poison: poison::FLAG_INIT,
@@ -109,7 +111,7 @@ pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock {
 /// RAII structure used to release the shared read access of a lock when
 /// dropped.
 #[must_use]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 #[cfg(stage0)] // NOTE remove impl after next snapshot
 pub struct RwLockReadGuard<'a, T: 'a> {
     __lock: &'a StaticRwLock,
@@ -120,8 +122,8 @@ pub struct RwLockReadGuard<'a, T: 'a> {
 /// RAII structure used to release the shared read access of a lock when
 /// dropped.
 #[must_use]
-#[stable]
 #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct RwLockReadGuard<'a, T: 'a> {
     __lock: &'a StaticRwLock,
     __data: &'a UnsafeCell<T>,
@@ -133,8 +135,8 @@ impl<'a, T> !marker::Send for RwLockReadGuard<'a, T> {}
 /// RAII structure used to release the exclusive write access of a lock when
 /// dropped.
 #[must_use]
-#[stable]
 #[cfg(stage0)] // NOTE remove impl after next snapshot
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct RwLockWriteGuard<'a, T: 'a> {
     __lock: &'a StaticRwLock,
     __data: &'a UnsafeCell<T>,
@@ -145,7 +147,7 @@ pub struct RwLockWriteGuard<'a, T: 'a> {
 /// RAII structure used to release the exclusive write access of a lock when
 /// dropped.
 #[must_use]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
 pub struct RwLockWriteGuard<'a, T: 'a> {
     __lock: &'a StaticRwLock,
@@ -158,7 +160,7 @@ impl<'a, T> !marker::Send for RwLockWriteGuard<'a, T> {}
 
 impl<T: Send + Sync> RwLock<T> {
     /// Creates a new instance of an RwLock which is unlocked and read to go.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn new(t: T) -> RwLock<T> {
         RwLock { inner: box RW_LOCK_INIT, data: UnsafeCell::new(t) }
     }
@@ -181,7 +183,7 @@ impl<T: Send + Sync> RwLock<T> {
     /// is poisoned whenever a writer panics while holding an exclusive lock.
     /// The failure will occur immediately after the lock has been acquired.
     #[inline]
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn read(&self) -> LockResult<RwLockReadGuard<T>> {
         unsafe { self.inner.lock.read() }
         RwLockReadGuard::new(&*self.inner, &self.data)
@@ -203,7 +205,7 @@ impl<T: Send + Sync> RwLock<T> {
     /// error will only be returned if the lock would have otherwise been
     /// acquired.
     #[inline]
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn try_read(&self) -> TryLockResult<RwLockReadGuard<T>> {
         if unsafe { self.inner.lock.try_read() } {
             Ok(try!(RwLockReadGuard::new(&*self.inner, &self.data)))
@@ -227,7 +229,7 @@ impl<T: Send + Sync> RwLock<T> {
     /// is poisoned whenever a writer panics while holding an exclusive lock.
     /// An error will be returned when the lock is acquired.
     #[inline]
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn write(&self) -> LockResult<RwLockWriteGuard<T>> {
         unsafe { self.inner.lock.write() }
         RwLockWriteGuard::new(&*self.inner, &self.data)
@@ -246,7 +248,7 @@ impl<T: Send + Sync> RwLock<T> {
     /// error will only be returned if the lock would have otherwise been
     /// acquired.
     #[inline]
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<T>> {
         if unsafe { self.inner.lock.try_read() } {
             Ok(try!(RwLockWriteGuard::new(&*self.inner, &self.data)))
@@ -257,7 +259,7 @@ impl<T: Send + Sync> RwLock<T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<T> Drop for RwLock<T> {
     fn drop(&mut self) {
         unsafe { self.inner.lock.destroy() }
@@ -274,7 +276,8 @@ impl StaticRwLock {
     ///
     /// See `RwLock::read`.
     #[inline]
-    #[unstable = "may be merged with RwLock in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with RwLock in the future")]
     pub fn read(&'static self) -> LockResult<RwLockReadGuard<'static, ()>> {
         unsafe { self.lock.read() }
         RwLockReadGuard::new(self, &DUMMY.0)
@@ -284,7 +287,8 @@ impl StaticRwLock {
     ///
     /// See `RwLock::try_read`.
     #[inline]
-    #[unstable = "may be merged with RwLock in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with RwLock in the future")]
     pub fn try_read(&'static self)
                     -> TryLockResult<RwLockReadGuard<'static, ()>> {
         if unsafe { self.lock.try_read() } {
@@ -299,7 +303,8 @@ impl StaticRwLock {
     ///
     /// See `RwLock::write`.
     #[inline]
-    #[unstable = "may be merged with RwLock in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with RwLock in the future")]
     pub fn write(&'static self) -> LockResult<RwLockWriteGuard<'static, ()>> {
         unsafe { self.lock.write() }
         RwLockWriteGuard::new(self, &DUMMY.0)
@@ -309,7 +314,8 @@ impl StaticRwLock {
     ///
     /// See `RwLock::try_write`.
     #[inline]
-    #[unstable = "may be merged with RwLock in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with RwLock in the future")]
     pub fn try_write(&'static self)
                      -> TryLockResult<RwLockWriteGuard<'static, ()>> {
         if unsafe { self.lock.try_write() } {
@@ -325,7 +331,8 @@ impl StaticRwLock {
     /// active users of the lock, and this also doesn't prevent any future users
     /// of this lock. This method is required to be called to not leak memory on
     /// all platforms.
-    #[unstable = "may be merged with RwLock in the future"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may be merged with RwLock in the future")]
     pub unsafe fn destroy(&'static self) {
         self.lock.destroy()
     }
@@ -382,19 +389,19 @@ impl<'rwlock, T> RwLockWriteGuard<'rwlock, T> {
     }
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'rwlock, T> Deref for RwLockReadGuard<'rwlock, T> {
     type Target = T;
 
     fn deref(&self) -> &T { unsafe { &*self.__data.get() } }
 }
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'rwlock, T> Deref for RwLockWriteGuard<'rwlock, T> {
     type Target = T;
 
     fn deref(&self) -> &T { unsafe { &*self.__data.get() } }
 }
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'rwlock, T> DerefMut for RwLockWriteGuard<'rwlock, T> {
     fn deref_mut(&mut self) -> &mut T {
         unsafe { &mut *self.__data.get() }
@@ -402,7 +409,7 @@ impl<'rwlock, T> DerefMut for RwLockWriteGuard<'rwlock, T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, T> Drop for RwLockReadGuard<'a, T> {
     fn drop(&mut self) {
         unsafe { self.__lock.lock.read_unlock(); }
@@ -410,7 +417,7 @@ impl<'a, T> Drop for RwLockReadGuard<'a, T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, T> Drop for RwLockWriteGuard<'a, T> {
     fn drop(&mut self) {
         self.__lock.poison.done(&self.__poison);
diff --git a/src/libstd/sync/semaphore.rs b/src/libstd/sync/semaphore.rs
index 8d44084671a..08b620c764a 100644
--- a/src/libstd/sync/semaphore.rs
+++ b/src/libstd/sync/semaphore.rs
@@ -8,8 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![unstable = "the interaction between semaphores and the acquisition/release \
-               of resources is currently unclear"]
+#![unstable(feature = "unnamed_feature", since = "1.0.0",
+            reason = "the interaction between semaphores and the acquisition/release \
+                      of resources is currently unclear")]
 
 use ops::Drop;
 use sync::{Mutex, Condvar};
@@ -99,7 +100,7 @@ impl Semaphore {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a> Drop for SemaphoreGuard<'a> {
     fn drop(&mut self) {
         self.sem.release();
diff --git a/src/libstd/sync/task_pool.rs b/src/libstd/sync/task_pool.rs
index 278528bdb38..ceec1885375 100644
--- a/src/libstd/sync/task_pool.rs
+++ b/src/libstd/sync/task_pool.rs
@@ -10,10 +10,11 @@
 
 //! Abstraction of a thread pool for basic parallelism.
 
-#![unstable = "the semantics of a failing task and whether a thread is \
-               re-attached to a thread pool are somewhat unclear, and the \
-               utility of this type in `std::sync` is questionable with \
-               respect to the jobs of other primitives"]
+#![unstable(feature = "unnamed_feature", since="1.0.0",
+            reason = "the semantics of a failing task and whether a thread is \
+                      re-attached to a thread pool are somewhat unclear, and the \
+                      utility of this type in `std::sync` is questionable with \
+                      respect to the jobs of other primitives")]
 
 use core::prelude::*;
 
diff --git a/src/libstd/sys/unix/ext.rs b/src/libstd/sys/unix/ext.rs
index 0e4a9d1b307..4e846a42030 100644
--- a/src/libstd/sys/unix/ext.rs
+++ b/src/libstd/sys/unix/ext.rs
@@ -29,7 +29,7 @@
 //! }
 //! ```
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 
 use sys_common::AsInner;
 use libc;
diff --git a/src/libstd/sys/windows/ext.rs b/src/libstd/sys/windows/ext.rs
index 87ff31ab73c..edc46b9c162 100644
--- a/src/libstd/sys/windows/ext.rs
+++ b/src/libstd/sys/windows/ext.rs
@@ -14,7 +14,7 @@
 //! descriptors, and sockets, but its functionality will grow over
 //! time.
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 
 use sys_common::AsInner;
 use libc;
diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs
index 932556fe1a6..7df7e750610 100644
--- a/src/libstd/thread.rs
+++ b/src/libstd/thread.rs
@@ -144,7 +144,7 @@
 //!
 //! * It can be implemented highly efficiently on many platforms.
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 
 use any::Any;
 use boxed::Box;
@@ -166,7 +166,7 @@ use sys_common::{stack, thread_info};
 
 /// Thread configuration. Provides detailed control over the properties
 /// and behavior of new threads.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Builder {
     // A name for the thread-to-be, for identification in panic messages
     name: Option<String>,
@@ -181,7 +181,7 @@ pub struct Builder {
 impl Builder {
     /// Generate the base configuration for spawning a thread, from which
     /// configuration methods can be chained.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn new() -> Builder {
         Builder {
             name: None,
@@ -193,28 +193,30 @@ impl Builder {
 
     /// Name the thread-to-be. Currently the name is used for identification
     /// only in panic messages.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn name(mut self, name: String) -> Builder {
         self.name = Some(name);
         self
     }
 
     /// Set the size of the stack for the new thread.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn stack_size(mut self, size: uint) -> Builder {
         self.stack_size = Some(size);
         self
     }
 
     /// Redirect thread-local stdout.
-    #[unstable = "Will likely go away after proc removal"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "Will likely go away after proc removal")]
     pub fn stdout(mut self, stdout: Box<Writer + Send>) -> Builder {
         self.stdout = Some(stdout);
         self
     }
 
     /// Redirect thread-local stderr.
-    #[unstable = "Will likely go away after proc removal"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "Will likely go away after proc removal")]
     pub fn stderr(mut self, stderr: Box<Writer + Send>) -> Builder {
         self.stderr = Some(stderr);
         self
@@ -223,7 +225,8 @@ impl Builder {
     /// Spawn a new detached thread, and return a handle to it.
     ///
     /// See `Thead::spawn` and the module doc for more details.
-    #[unstable = "may change with specifics of new Send semantics"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may change with specifics of new Send semantics")]
     pub fn spawn<F>(self, f: F) -> Thread where F: FnOnce(), F: Send + 'static {
         let (native, thread) = self.spawn_inner(Thunk::new(f), Thunk::with_arg(|_| {}));
         unsafe { imp::detach(native) };
@@ -234,7 +237,8 @@ impl Builder {
     /// scope, and return a `JoinGuard`.
     ///
     /// See `Thead::scoped` and the module doc for more details.
-    #[unstable = "may change with specifics of new Send semantics"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may change with specifics of new Send semantics")]
     pub fn scoped<'a, T, F>(self, f: F) -> JoinGuard<'a, T> where
         T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
     {
@@ -326,7 +330,7 @@ struct Inner {
 unsafe impl Sync for Inner {}
 
 #[derive(Clone)]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 /// A handle to a thread.
 pub struct Thread {
     inner: Arc<Inner>,
@@ -350,7 +354,8 @@ impl Thread {
     /// main thread; the whole process is terminated when the main thread
     /// finishes.) The thread handle can be used for low-level
     /// synchronization. See the module documentation for additional details.
-    #[unstable = "may change with specifics of new Send semantics"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may change with specifics of new Send semantics")]
     pub fn spawn<F>(f: F) -> Thread where F: FnOnce(), F: Send + 'static {
         Builder::new().spawn(f)
     }
@@ -363,7 +368,8 @@ impl Thread {
     /// current thread's stack (hence the "scoped" name), it cannot be detached;
     /// it *must* be joined before the relevant stack frame is popped. See the
     /// module documentation for additional details.
-    #[unstable = "may change with specifics of new Send semantics"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "may change with specifics of new Send semantics")]
     pub fn scoped<'a, T, F>(f: F) -> JoinGuard<'a, T> where
         T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
     {
@@ -371,20 +377,20 @@ impl Thread {
     }
 
     /// Gets a handle to the thread that invokes it.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn current() -> Thread {
         thread_info::current_thread()
     }
 
     /// Cooperatively give up a timeslice to the OS scheduler.
-    #[unstable = "name may change"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "name may change")]
     pub fn yield_now() {
         unsafe { imp::yield_now() }
     }
 
     /// Determines whether the current thread is panicking.
     #[inline]
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn panicking() -> bool {
         unwind::panicking()
     }
@@ -398,7 +404,7 @@ impl Thread {
     // future, this will be implemented in a more efficient way, perhaps along the lines of
     //   http://cr.openjdk.java.net/~stefank/6989984.1/raw_files/new/src/os/linux/vm/os_linux.cpp
     // or futuxes, and in either case may allow spurious wakeups.
-    #[unstable = "recently introduced"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "recently introduced")]
     pub fn park() {
         let thread = Thread::current();
         let mut guard = thread.inner.lock.lock().unwrap();
@@ -411,7 +417,7 @@ impl Thread {
     /// Atomically makes the handle's token available if it is not already.
     ///
     /// See the module doc for more detail.
-    #[unstable = "recently introduced"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0", reason = "recently introduced")]
     pub fn unpark(&self) {
         let mut guard = self.inner.lock.lock().unwrap();
         if !*guard {
@@ -421,7 +427,7 @@ impl Thread {
     }
 
     /// Get the thread's name.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn name(&self) -> Option<&str> {
         self.inner.name.as_ref().map(|s| s.as_slice())
     }
@@ -435,7 +441,7 @@ impl thread_info::NewThread for Thread {
 /// Indicates the manner in which a thread exited.
 ///
 /// A thread that completes without panicking is considered to exit successfully.
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub type Result<T> = ::result::Result<T, Box<Any + Send>>;
 
 struct Packet<T>(Arc<UnsafeCell<Option<Result<T>>>>);
@@ -447,7 +453,8 @@ unsafe impl<T> Sync for Packet<T> {}
 ///
 /// The type `T` is the return type for the thread's main function.
 #[must_use]
-#[unstable = "may change with specifics of new Send semantics"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "may change with specifics of new Send semantics")]
 pub struct JoinGuard<'a, T: 'a> {
     native: imp::rust_thread,
     thread: Thread,
@@ -455,12 +462,12 @@ pub struct JoinGuard<'a, T: 'a> {
     packet: Packet<T>,
 }
 
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 unsafe impl<'a, T: Send + 'a> Sync for JoinGuard<'a, T> {}
 
 impl<'a, T: Send + 'a> JoinGuard<'a, T> {
     /// Extract a handle to the thread this guard will join on.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn thread(&self) -> &Thread {
         &self.thread
     }
@@ -470,7 +477,7 @@ impl<'a, T: Send + 'a> JoinGuard<'a, T> {
     ///
     /// If the child thread panics, `Err` is returned with the parameter given
     /// to `panic`.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn join(mut self) -> Result<T> {
         assert!(!self.joined);
         unsafe { imp::join(self.native) };
@@ -483,7 +490,8 @@ impl<'a, T: Send + 'a> JoinGuard<'a, T> {
 
 impl<T: Send> JoinGuard<'static, T> {
     /// Detaches the child thread, allowing it to outlive its parent.
-    #[unstable = "unsure whether this API imposes limitations elsewhere"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "unsure whether this API imposes limitations elsewhere")]
     pub fn detach(mut self) {
         unsafe { imp::detach(self.native) };
         self.joined = true; // avoid joining in the destructor
@@ -491,7 +499,7 @@ impl<T: Send> JoinGuard<'static, T> {
 }
 
 #[unsafe_destructor]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 impl<'a, T: Send + 'a> Drop for JoinGuard<'a, T> {
     fn drop(&mut self) {
         if !self.joined {
diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs
index 4c99cff34da..bf74acda721 100644
--- a/src/libstd/thread_local/mod.rs
+++ b/src/libstd/thread_local/mod.rs
@@ -34,7 +34,7 @@
 //! will want to make use of some form of **interior mutability** through the
 //! `Cell` or `RefCell` types.
 
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 
 use prelude::v1::*;
 
@@ -93,7 +93,7 @@ pub mod __impl {
 ///     assert_eq!(*f.borrow(), 2);
 /// });
 /// ```
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct Key<T> {
     // The key itself may be tagged with #[thread_local], and this `Key` is
     // stored as a `static`, and it's not valid for a static to reference the
@@ -113,7 +113,7 @@ pub struct Key<T> {
 
 /// Declare a new thread local storage key of type `std::thread_local::Key`.
 #[macro_export]
-#[stable]
+#[stable(feature = "grandfathered", since = "1.0.0")]
 macro_rules! thread_local {
     (static $name:ident: $t:ty = $init:expr) => (
         static $name: ::std::thread_local::Key<$t> = {
@@ -218,7 +218,8 @@ macro_rules! __thread_local_inner {
 }
 
 /// Indicator of the state of a thread local storage key.
-#[unstable = "state querying was recently added"]
+#[unstable(feature = "unnamed_feature", since = "1.0.0",
+           reason = "state querying was recently added")]
 #[derive(Eq, PartialEq, Copy)]
 pub enum State {
     /// All keys are in this state whenever a thread starts. Keys will
@@ -258,7 +259,7 @@ impl<T: 'static> Key<T> {
     /// This function will `panic!()` if the key currently has its
     /// destructor running, and it **may** panic if the destructor has
     /// previously been run for this thread.
-    #[stable]
+    #[stable(feature = "grandfathered", since = "1.0.0")]
     pub fn with<F, R>(&'static self, f: F) -> R
                       where F: FnOnce(&T) -> R {
         let slot = (self.inner)();
@@ -301,7 +302,8 @@ impl<T: 'static> Key<T> {
     /// initialization does not panic. Keys in the `Valid` state are guaranteed
     /// to be able to be accessed. Keys in the `Destroyed` state will panic on
     /// any call to `with`.
-    #[unstable = "state querying was recently added"]
+    #[unstable(feature = "unnamed_feature", since = "1.0.0",
+               reason = "state querying was recently added")]
     pub fn state(&'static self) -> State {
         unsafe {
             match (self.inner)().get() {
@@ -317,7 +319,8 @@ impl<T: 'static> Key<T> {
     }
 
     /// Deprecated
-    #[deprecated = "function renamed to state() and returns more info"]
+    #[deprecated(feature = "oldstuff", since = "1.0.0",
+                 reason = "function renamed to state() and returns more info")]
     pub fn destroyed(&'static self) -> bool { self.state() == State::Destroyed }
 }
 
diff --git a/src/libstd/thread_local/scoped.rs b/src/libstd/thread_local/scoped.rs
index 1fb5652bc0c..e7062b298d2 100644
--- a/src/libstd/thread_local/scoped.rs
+++ b/src/libstd/thread_local/scoped.rs
@@ -38,8 +38,9 @@
 //! });
 //! ```
 
-#![unstable = "scoped TLS has yet to have wide enough use to fully consider \
-               stabilizing its interface"]
+#![unstable(feature = "unnamed_feature", since = "1.0.0",
+            reason = "scoped TLS has yet to have wide enough use to fully consider \
+                      stabilizing its interface")]
 
 use prelude::v1::*;
 
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index 162c3677168..90fd3b0138f 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -10,7 +10,7 @@
 
 //! Temporal quantification
 
-#![unstable]
+#![unstable(feature = "unnamed_feature", since = "1.0.0")]
 
 use {fmt, i64};
 use ops::{Add, Sub, Mul, Div, Neg, FnOnce};
diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs
index e76dcef226d..b06deb738fc 100644
--- a/src/libstd/tuple.rs
+++ b/src/libstd/tuple.rs
@@ -57,4 +57,4 @@
 //! ```
 
 #![doc(primitive = "tuple")]
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
diff --git a/src/libstd/unit.rs b/src/libstd/unit.rs
index 012b175b031..0893fe8ea06 100644
--- a/src/libstd/unit.rs
+++ b/src/libstd/unit.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #![doc(primitive = "unit")]
-#![stable]
+#![stable(feature = "grandfathered", since = "1.0.0")]
 
 //! The `()` type, sometimes called "unit" or "nil".
 //!