about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2015-01-22 12:33:46 -0800
committerBrian Anderson <banderson@mozilla.com>2015-01-23 15:50:03 -0800
commit9758c488a94e77cc8a110a6783a99cf5b91326db (patch)
treeca5f2436cb4b9dc39aa7f525cf4a5fc9288d0ac7
parentcd6d9eab5d75584edfcae4ffdef8b0836db80c1e (diff)
downloadrust-9758c488a94e77cc8a110a6783a99cf5b91326db.tar.gz
rust-9758c488a94e77cc8a110a6783a99cf5b91326db.zip
Deprecated attributes don't take 'feature' names and are paired with stable/unstable
Conflicts:
	src/libcore/atomic.rs
	src/libcore/finally.rs
	src/test/auxiliary/inherited_stability.rs
	src/test/auxiliary/lint_stability.rs
-rw-r--r--src/etc/featureck.py33
-rw-r--r--src/libarena/lib.rs2
-rw-r--r--src/libcollections/lib.rs1
-rw-r--r--src/libcollections/slice.rs3
-rw-r--r--src/libcore/atomic.rs12
-rw-r--r--src/libcore/finally.rs3
-rw-r--r--src/libcore/hash/sip.rs3
-rw-r--r--src/libcore/num/f32.rs30
-rw-r--r--src/libcore/num/f64.rs30
-rw-r--r--src/libcore/num/int.rs3
-rw-r--r--src/libcore/num/mod.rs30
-rw-r--r--src/libcore/num/uint.rs3
-rw-r--r--src/libcore/str/mod.rs3
-rw-r--r--src/libgetopts/lib.rs4
-rw-r--r--src/libgraphviz/maybe_owned_vec.rs3
-rw-r--r--src/liblibc/lib.rs1
-rw-r--r--src/librustc/lint/builtin.rs2
-rw-r--r--src/librustc/middle/stability.rs31
-rw-r--r--src/librustc_trans/lib.rs1
-rw-r--r--src/librustdoc/html/format.rs11
-rw-r--r--src/librustdoc/stability_summary.rs14
-rw-r--r--src/libserialize/lib.rs1
-rw-r--r--src/libstd/io/mem.rs3
-rw-r--r--src/libstd/lib.rs1
-rw-r--r--src/libstd/num/int.rs3
-rw-r--r--src/libstd/num/mod.rs21
-rw-r--r--src/libstd/num/uint.rs3
-rw-r--r--src/libstd/prelude/mod.rs1
-rw-r--r--src/libstd/sync/poison.rs3
-rw-r--r--src/libstd/thread_local/mod.rs3
-rw-r--r--src/libsyntax/attr.rs100
-rw-r--r--src/libsyntax/ext/base.rs3
-rw-r--r--src/libsyntax/util/small_vector.rs3
-rw-r--r--src/test/auxiliary/inherited_stability.rs3
-rwxr-xr-xsrc/test/auxiliary/lint_output_format.rs3
-rw-r--r--src/test/auxiliary/lint_stability.rs63
-rw-r--r--src/test/compile-fail/issue-17337.rs3
-rw-r--r--src/test/compile-fail/lint-stability.rs71
-rw-r--r--src/test/compile-fail/stability-attribute-sanity.rs95
39 files changed, 437 insertions, 169 deletions
diff --git a/src/etc/featureck.py b/src/etc/featureck.py
index 360d6380a29..3327548581a 100644
--- a/src/etc/featureck.py
+++ b/src/etc/featureck.py
@@ -84,8 +84,6 @@ for (dirpath, dirnames, filenames) in os.walk(src_dir):
                     level = "unstable"
                 elif "[stable(" in line:
                     level = "stable"
-                elif "[deprecated(" in line:
-                    level = "deprecated"
                 else:
                     continue
 
@@ -94,12 +92,12 @@ for (dirpath, dirnames, filenames) in os.walk(src_dir):
                 # the same line, e.g.
                 # `#[unstable(feature = "foo", since = "1.0.0")]`
 
-                p = re.compile('(unstable|stable|deprecated).*feature *= *"(\w*)"')
+                p = re.compile('(unstable|stable).*feature *= *"(\w*)"')
                 m = p.search(line)
                 if not m is None:
                     feature_name = m.group(2)
                     since = None
-                    if "stable" in line or "deprecated" in line:
+                    if "stable" in line:
                         pp = re.compile('since *= *"([\w\.]*)"')
                         mm = pp.search(line)
                         since = m.group(1)
@@ -135,7 +133,7 @@ for (dirpath, dirnames, filenames) in os.walk(src_dir):
                     errors = True
 
 # Merge data about both lists
-# name, lang, lib, status, stable since, partially deprecated
+# name, lang, lib, status, stable since
 
 language_feature_stats = {}
 
@@ -145,15 +143,13 @@ for f in language_features:
     lib = False
     status = "unstable"
     stable_since = None
-    partially_deprecated = False
 
     if f[2] == "Accepted":
         status = "stable"
     if status == "stable":
         stable_since = f[1]
 
-    language_feature_stats[name] = (name, lang, lib, status, stable_since, \
-                                    partially_deprecated)
+    language_feature_stats[name] = (name, lang, lib, status, stable_since)
 
 lib_feature_stats = {}
 
@@ -163,11 +159,9 @@ for f in lib_features:
     lib = True
     status = "unstable"
     stable_since = None
-    partially_deprecated = False
 
     is_stable = lib_features_and_level.get((name, "stable")) is not None
     is_unstable = lib_features_and_level.get((name, "unstable")) is not None
-    is_deprecated = lib_features_and_level.get((name, "deprecated")) is not None
 
     if is_stable and is_unstable:
         print "error: feature '" + name + "' is both stable and unstable"
@@ -179,14 +173,8 @@ for f in lib_features:
     elif is_unstable:
         status = "unstable"
         stable_since = lib_features_and_level[(name, "unstable")][0]
-    elif is_deprecated:
-        status = "deprecated"
 
-    if (is_stable or is_unstable) and is_deprecated:
-        partially_deprecated = True
-
-    lib_feature_stats[name] = (name, lang, lib, status, stable_since, \
-                               partially_deprecated)
+    lib_feature_stats[name] = (name, lang, lib, status, stable_since)
 
 # Check for overlap in two sets
 merged_stats = { }
@@ -200,25 +188,18 @@ for name in lib_feature_stats:
         lib_status = lib_feature_stats[name][3]
         lang_stable_since = lang_feature_stats[name][4]
         lib_stable_since = lib_feature_stats[name][4]
-        lang_partially_deprecated = lang_feature_stats[name][5]
-        lib_partially_deprecated = lib_feature_stats[name][5]
 
         if lang_status != lib_status and lib_status != "deprecated":
             print "error: feature '" + name + "' has lang status " + lang_status + \
                   " but lib status " + lib_status
             errors = True
 
-        partially_deprecated = lang_partially_deprecated or lib_partially_deprecated
-        if lib_status == "deprecated" and lang_status != "deprecated":
-            partially_deprecated = True
-
         if lang_stable_since != lib_stable_since:
             print "error: feature '" + name + "' has lang stable since " + lang_stable_since + \
                   " but lib stable since " + lib_stable_since
             errors = True
 
-        merged_stats[name] = (name, True, True, lang_status, lang_stable_since, \
-                              partially_deprecated)
+        merged_stats[name] = (name, True, True, lang_status, lang_stable_since)
 
         del language_feature_stats[name]
         del lib_feature_stats[name]
@@ -244,8 +225,6 @@ for s in stats:
            "{: <8}".format(type_) + \
            "{: <12}".format(s[3]) + \
            "{: <8}".format(str(s[4]))
-    if s[5]:
-        line += "(partially deprecated)"
     lines += [line]
 
 lines.sort()
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index de0f15dd08d..9396e2d6fb2 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -37,6 +37,8 @@
 #![allow(missing_docs)]
 #![feature(alloc)]
 #![feature(core)]
+#![cfg_attr(test, feature(test))]
+#![cfg_attr(test, feature(collections))]
 
 extern crate alloc;
 
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index b836fe61a75..b5725e63327 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -33,6 +33,7 @@
 #![feature(alloc)]
 #![feature(unicode)]
 #![feature(hash)]
+#![cfg_attr(test, feature(test))]
 
 #[macro_use]
 extern crate core;
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index 6765eda4cb7..869b8539494 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -642,7 +642,8 @@ pub trait SliceExt {
     fn binary_search(&self, x: &Self::Item) -> Result<uint, uint> where Self::Item: Ord;
 
     /// Deprecated: use `binary_search` instead.
-    #[deprecated(feature = "oldstuff", since = "1.0.0", reason = "use binary_search instead")]
+    #[unstable(feature = "collections")]
+    #[deprecated(since = "1.0.0", reason = "use binary_search instead")]
     fn binary_search_elem(&self, x: &Self::Item) -> Result<uint, uint> where Self::Item: Ord {
         self.binary_search(x)
     }
diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs
index e4e6fcd3afc..5f48c965e70 100644
--- a/src/libcore/atomic.rs
+++ b/src/libcore/atomic.rs
@@ -1036,7 +1036,8 @@ pub fn fence(order: Ordering) {
     }
 }
 
-#[deprecated(feature = "core", since = "1.0.0",
+#[unstable(feature = "core")]
+#[deprecated(since = "1.0.0",
              reason = "renamed to AtomicIsize")]
 #[allow(missing_docs)]
 pub struct AtomicInt {
@@ -1045,7 +1046,8 @@ pub struct AtomicInt {
 
 unsafe impl Sync for AtomicInt {}
 
-#[deprecated(feature = "core", since = "1.0.0",
+#[unstable(feature = "core")]
+#[deprecated(since = "1.0.0",
              reason = "renamed to AtomicUsize")]
 #[allow(missing_docs)]
 pub struct AtomicUint {
@@ -1054,12 +1056,14 @@ pub struct AtomicUint {
 
 unsafe impl Sync for AtomicUint {}
 
-#[deprecated(feature = "core", since = "1.0.0",
+#[unstable(feature = "core")]
+#[deprecated(since = "1.0.0",
              reason = "use ATOMIC_ISIZE_INIT instead")]
 #[allow(missing_docs, deprecated)]
 pub const ATOMIC_INT_INIT: AtomicInt =
         AtomicInt { v: UnsafeCell { value: 0 } };
-#[deprecated(feature = "core", since = "1.0.0",
+#[unstable(feature = "core")]
+#[deprecated(since = "1.0.0",
              reason = "use ATOMIC_USIZE_INIT instead")]
 #[allow(missing_docs, deprecated)]
 pub const ATOMIC_UINT_INIT: AtomicUint =
diff --git a/src/libcore/finally.rs b/src/libcore/finally.rs
index 2bd90e7c964..0f444ef186f 100644
--- a/src/libcore/finally.rs
+++ b/src/libcore/finally.rs
@@ -30,7 +30,8 @@
 //! })
 //! ```
 
-#![deprecated(feature = "core", since = "1.0.0",
+#![unstable(feature = "core")]
+#![deprecated(since = "1.0.0",
               reason = "It is unclear if this module is more robust than implementing \
                         Drop on a custom type, and this module is being removed with no \
                         replacement. Use a custom Drop implementation to regain existing \
diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs
index 1492547de44..dcb010d8bc3 100644
--- a/src/libcore/hash/sip.rs
+++ b/src/libcore/hash/sip.rs
@@ -112,7 +112,8 @@ impl SipHasher {
     }
 
     /// Returns the computed hash.
-    #[deprecated(feature = "oldstuff", since = "1.0.0", reason = "renamed to finish")]
+    #[unstable(feature = "hash")]
+    #[deprecated(since = "1.0.0", reason = "renamed to finish")]
     pub fn result(&self) -> u64 { self.finish() }
 }
 
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 8e28bb18aef..b3733efe7b3 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -178,43 +178,53 @@ impl Float for f32 {
     }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn mantissa_digits(_: Option<f32>) -> uint { MANTISSA_DIGITS }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn digits(_: Option<f32>) -> uint { DIGITS }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn epsilon() -> f32 { EPSILON }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn min_exp(_: Option<f32>) -> int { MIN_EXP }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn max_exp(_: Option<f32>) -> int { MAX_EXP }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn min_10_exp(_: Option<f32>) -> int { MIN_10_EXP }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn max_10_exp(_: Option<f32>) -> int { MAX_10_EXP }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn min_value() -> f32 { MIN_VALUE }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn min_pos_value(_: Option<f32>) -> f32 { MIN_POS_VALUE }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn max_value() -> f32 { MAX_VALUE }
 
     /// Returns the mantissa, exponent and sign as integers.
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 4fee89e923c..8a3767068df 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -185,43 +185,53 @@ impl Float for f64 {
     }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn mantissa_digits(_: Option<f64>) -> uint { MANTISSA_DIGITS }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn digits(_: Option<f64>) -> uint { DIGITS }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn epsilon() -> f64 { EPSILON }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn min_exp(_: Option<f64>) -> int { MIN_EXP }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn max_exp(_: Option<f64>) -> int { MAX_EXP }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn min_10_exp(_: Option<f64>) -> int { MIN_10_EXP }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn max_10_exp(_: Option<f64>) -> int { MAX_10_EXP }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn min_value() -> f64 { MIN_VALUE }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn min_pos_value(_: Option<f64>) -> f64 { MIN_POS_VALUE }
 
     #[inline]
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0")]
     fn max_value() -> f64 { MAX_VALUE }
 
     /// Returns the mantissa, exponent and sign as integers.
diff --git a/src/libcore/num/int.rs b/src/libcore/num/int.rs
index 4b4e408ddd7..2132b9516ab 100644
--- a/src/libcore/num/int.rs
+++ b/src/libcore/num/int.rs
@@ -14,7 +14,8 @@
 //! alpha cycle along with the development of clearer conventions
 //! around integer types.
 
-#![deprecated(feature = "oldstuff", since = "1.0.0", reason = "replaced by isize")]
+#![unstable(feature = "core")]
+#![deprecated(since = "1.0.0", reason = "replaced by isize")]
 
 #[cfg(target_pointer_width = "32")] int_module! { int, 32 }
 #[cfg(target_pointer_width = "64")] int_module! { int, 64 }
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 5e4956dfccf..09dbec93bf0 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -1292,45 +1292,55 @@ pub trait Float
     // FIXME (#5527): These should be associated constants
 
     /// Returns the number of binary digits of mantissa that this type supports.
-    #[deprecated(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "core")]
+    #[deprecated(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(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "core")]
+    #[deprecated(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(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "core")]
+    #[deprecated(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(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "core")]
+    #[deprecated(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(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "core")]
+    #[deprecated(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(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "core")]
+    #[deprecated(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(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "core")]
+    #[deprecated(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.
-    #[deprecated(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MIN_VALUE` or `std::f64::MIN_VALUE` as appropriate")]
     fn min_value() -> Self;
     /// Returns the smallest normalized positive number that this type can represent.
-    #[deprecated(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MIN_POS_VALUE` or \
                            `std::f64::MIN_POS_VALUE` as appropriate")]
     fn min_pos_value(unused_self: Option<Self>) -> Self;
     /// Returns the largest finite value that this type can represent.
-    #[deprecated(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "core")]
+    #[deprecated(since = "1.0.0",
                  reason = "use `std::f32::MAX_VALUE` or `std::f64::MAX_VALUE` as appropriate")]
     fn max_value() -> Self;
 
diff --git a/src/libcore/num/uint.rs b/src/libcore/num/uint.rs
index 42f9c56c725..f66a0eed971 100644
--- a/src/libcore/num/uint.rs
+++ b/src/libcore/num/uint.rs
@@ -14,6 +14,7 @@
 //! alpha cycle along with the development of clearer conventions
 //! around integer types.
 
-#![deprecated(feature = "oldstuff", since = "1.0.0", reason = "replaced by usize")]
+#![unstable(feature = "core")]
+#![deprecated(since = "1.0.0", reason = "replaced by usize")]
 
 uint_module! { uint, int, ::int::BITS }
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 8daf71edb33..d487d135df4 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -195,7 +195,8 @@ pub unsafe fn from_utf8_unchecked<'a>(v: &'a [u8]) -> &'a str {
 /// # Panics
 ///
 /// This function will panic if the string pointed to by `s` is not valid UTF-8.
-#[deprecated(feature = "oldstuff", since = "1.0.0",
+#[unstable(feature = "core")]
+#[deprecated(since = "1.0.0",
              reason = "use std::ffi::c_str_to_bytes + str::from_utf8")]
 pub unsafe fn from_c_str(s: *const i8) -> &'static str {
     let s = s as *const u8;
diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs
index c7ccebb7ce8..f62ffccabcc 100644
--- a/src/libgetopts/lib.rs
+++ b/src/libgetopts/lib.rs
@@ -93,6 +93,7 @@
 #![deny(missing_docs)]
 #![feature(collections)]
 #![feature(core)]
+#![cfg_attr(test, feature(rustc_private))]
 
 #[cfg(test)] #[macro_use] extern crate log;
 
@@ -541,7 +542,8 @@ pub fn opt(short_name: &str,
 
 impl Fail {
     /// Convert a `Fail` enum into an error string.
-    #[deprecated(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "rustc_private")]
+    #[deprecated(since = "1.0.0",
                  reason = "use `fmt::String` (`{}` format specifier)")]
     pub fn to_err_msg(self) -> String {
         self.to_string()
diff --git a/src/libgraphviz/maybe_owned_vec.rs b/src/libgraphviz/maybe_owned_vec.rs
index e93159eca21..4f21ce411ee 100644
--- a/src/libgraphviz/maybe_owned_vec.rs
+++ b/src/libgraphviz/maybe_owned_vec.rs
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deprecated(feature = "oldstuff", since = "1.0.0", reason = "use std::vec::CowVec")]
+#![unstable(feature = "rustc_private")]
+#![deprecated(since = "1.0.0", reason = "use std::vec::CowVec")]
 
 pub use self::MaybeOwnedVector::*;
 
diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs
index c1de5a627be..ee5df1d6d2f 100644
--- a/src/liblibc/lib.rs
+++ b/src/liblibc/lib.rs
@@ -21,6 +21,7 @@
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/",
        html_playground_url = "http://play.rust-lang.org/")]
+#![cfg_attr(test, feature(test))]
 
 //! Bindings for the C standard library and other platform libraries
 //!
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 8acf8b1032f..e73771649d5 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -1637,7 +1637,7 @@ impl Stability {
 
         // deprecated attributes apply in-crate and cross-crate
         let (lint, label) = match *stability {
-            Some(attr::Stability { level: attr::Deprecated, .. }) =>
+            Some(attr::Stability { deprecated_since: Some(_), .. }) =>
                 (DEPRECATED, "deprecated"),
             _ => return
         };
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index cf8f479b5bd..5c28e4c9d80 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -52,10 +52,10 @@ impl<'a> Annotator<'a> {
     // Determine the stability for a node based on its attributes and inherited
     // stability. The stability is recorded in the index and used as the parent.
     fn annotate<F>(&mut self, id: NodeId, use_parent: bool,
-                   attrs: &Vec<Attribute>, f: F) where
+                   attrs: &Vec<Attribute>, item_sp: Span, f: F) where
         F: FnOnce(&mut Annotator),
     {
-        match attr::find_stability(self.sess.diagnostic(), attrs.as_slice()) {
+        match attr::find_stability(self.sess.diagnostic(), attrs.as_slice(), item_sp) {
             Some(stab) => {
                 self.index.local.insert(id, stab.clone());
 
@@ -93,53 +93,54 @@ impl<'a, 'v> Visitor<'v> for Annotator<'a> {
             _ => true,
         };
 
-        self.annotate(i.id, use_parent, &i.attrs, |v| visit::walk_item(v, i));
+        self.annotate(i.id, use_parent, &i.attrs, i.span, |v| visit::walk_item(v, i));
 
         if let ast::ItemStruct(ref sd, _) = i.node {
             sd.ctor_id.map(|id| {
-                self.annotate(id, true, &i.attrs, |_| {})
+                self.annotate(id, true, &i.attrs, i.span, |_| {})
             });
         }
     }
 
     fn visit_fn(&mut self, fk: FnKind<'v>, _: &'v FnDecl,
-                _: &'v Block, _: Span, _: NodeId) {
+                _: &'v Block, sp: Span, _: NodeId) {
         if let FkMethod(_, _, meth) = fk {
             // Methods are not already annotated, so we annotate it
-            self.annotate(meth.id, true, &meth.attrs, |_| {});
+            self.annotate(meth.id, true, &meth.attrs, sp, |_| {});
         }
         // Items defined in a function body have no reason to have
         // a stability attribute, so we don't recurse.
     }
 
     fn visit_trait_item(&mut self, t: &TraitItem) {
-        let (id, attrs) = match *t {
-            RequiredMethod(TypeMethod {id, ref attrs, ..}) => (id, attrs),
+        let (id, attrs, sp) = match *t {
+            RequiredMethod(TypeMethod {id, ref attrs, span, ..}) => (id, attrs, span),
 
             // work around lack of pattern matching for @ types
             ProvidedMethod(ref method) => {
                 match **method {
-                    Method {ref attrs, id, ..} => (id, attrs),
+                    Method {ref attrs, id, span, ..} => (id, attrs, span),
                 }
             }
 
-            TypeTraitItem(ref typedef) => (typedef.ty_param.id, &typedef.attrs),
+            TypeTraitItem(ref typedef) => (typedef.ty_param.id, &typedef.attrs,
+                                           typedef.ty_param.span),
         };
-        self.annotate(id, true, attrs, |v| visit::walk_trait_item(v, t));
+        self.annotate(id, true, attrs, sp, |v| visit::walk_trait_item(v, t));
     }
 
     fn visit_variant(&mut self, var: &Variant, g: &'v Generics) {
-        self.annotate(var.node.id, true, &var.node.attrs,
+        self.annotate(var.node.id, true, &var.node.attrs, var.span,
                       |v| visit::walk_variant(v, var, g))
     }
 
     fn visit_struct_field(&mut self, s: &StructField) {
-        self.annotate(s.node.id, true, &s.node.attrs,
+        self.annotate(s.node.id, true, &s.node.attrs, s.span,
                       |v| visit::walk_struct_field(v, s));
     }
 
     fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
-        self.annotate(i.id, true, &i.attrs, |_| {});
+        self.annotate(i.id, true, &i.attrs, i.span, |_| {});
     }
 }
 
@@ -171,7 +172,7 @@ impl Index {
             index: index,
             parent: None
         };
-        annotator.annotate(ast::CRATE_NODE_ID, true, &krate.attrs,
+        annotator.annotate(ast::CRATE_NODE_ID, true, &krate.attrs, krate.span,
                            |v| visit::walk_crate(v, krate));
         annotator.index
     }
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 049cc0bd0da..bb026e237df 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -40,6 +40,7 @@
 #![feature(rustc_private)]
 #![feature(std_misc)]
 #![feature(unicode)]
+#![feature(hash)]
 
 extern crate arena;
 extern crate flate;
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 012b417a552..255ce03c586 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -765,9 +765,6 @@ impl fmt::String for ModuleSummary {
             try!(write!(f, "<span class='summary Unstable' \
                             style='width: {:.4}%; display: inline-block'>&nbsp</span>",
                         (100 * cnt.unstable) as f64/tot as f64));
-            try!(write!(f, "<span class='summary Deprecated' \
-                            style='width: {:.4}%; display: inline-block'>&nbsp</span>",
-                        (100 * cnt.deprecated) as f64/tot as f64));
             try!(write!(f, "<span class='summary Unmarked' \
                             style='width: {:.4}%; display: inline-block'>&nbsp</span>",
                         (100 * cnt.unmarked) as f64/tot as f64));
@@ -783,12 +780,11 @@ impl fmt::String for ModuleSummary {
         let mut context = Vec::new();
 
         let tot = self.counts.total();
-        let (stable, unstable, deprecated, unmarked) = if tot == 0 {
-            (0, 0, 0, 0)
+        let (stable, unstable, unmarked) = if tot == 0 {
+            (0, 0, 0)
         } else {
             ((100 * self.counts.stable)/tot,
              (100 * self.counts.unstable)/tot,
-             (100 * self.counts.deprecated)/tot,
              (100 * self.counts.unmarked)/tot)
         };
 
@@ -800,12 +796,11 @@ its children (percentages total for {name}):
 <blockquote>
 <a class='stability Stable'></a> stable ({}%),<br/>
 <a class='stability Unstable'></a> unstable ({}%),<br/>
-<a class='stability Deprecated'></a> deprecated ({}%),<br/>
 <a class='stability Unmarked'></a> unmarked ({}%)
 </blockquote>
 The counts do not include methods or trait
 implementations that are visible only through a re-exported type.",
-stable, unstable, deprecated, unmarked,
+stable, unstable, unmarked,
 name=self.name));
         try!(write!(f, "<table>"));
         try!(fmt_inner(f, &mut context, self));
diff --git a/src/librustdoc/stability_summary.rs b/src/librustdoc/stability_summary.rs
index b03b3239dab..9e6986d7846 100644
--- a/src/librustdoc/stability_summary.rs
+++ b/src/librustdoc/stability_summary.rs
@@ -16,7 +16,7 @@
 use std::cmp::Ordering;
 use std::ops::Add;
 
-use syntax::attr::{Deprecated, Unstable, Stable};
+use syntax::attr::{Unstable, Stable};
 use syntax::ast::Public;
 
 use clean::{Crate, Item, ModuleItem, Module, EnumItem, Enum};
@@ -29,7 +29,6 @@ use html::render::cache;
 /// The counts for each stability level.
 #[derive(Copy)]
 pub struct Counts {
-    pub deprecated: uint,
     pub unstable: uint,
     pub stable: uint,
 
@@ -42,7 +41,6 @@ impl Add for Counts {
 
     fn add(self, other: Counts) -> Counts {
         Counts {
-            deprecated:   self.deprecated   + other.deprecated,
             unstable:     self.unstable     + other.unstable,
             stable:       self.stable       + other.stable,
             unmarked:     self.unmarked     + other.unmarked,
@@ -53,7 +51,6 @@ impl Add for Counts {
 impl Counts {
     fn zero() -> Counts {
         Counts {
-            deprecated:   0,
             unstable:     0,
             stable:       0,
             unmarked:     0,
@@ -61,7 +58,7 @@ impl Counts {
     }
 
     pub fn total(&self) -> uint {
-        self.deprecated + self.unstable + self.stable + self.unmarked
+        self.unstable + self.stable + self.unmarked
     }
 }
 
@@ -96,11 +93,10 @@ fn visible(item: &Item) -> bool {
 
 fn count_stability(stab: Option<&Stability>) -> Counts {
     match stab {
-        None             => Counts { unmarked: 1,     .. Counts::zero() },
+        None            => Counts { unmarked: 1,     .. Counts::zero() },
         Some(ref stab) => match stab.level {
-            Deprecated   => Counts { deprecated: 1,   .. Counts::zero() },
-            Unstable     => Counts { unstable: 1,     .. Counts::zero() },
-            Stable       => Counts { stable: 1,       .. Counts::zero() },
+            Unstable    => Counts { unstable: 1,     .. Counts::zero() },
+            Stable      => Counts { stable: 1,       .. Counts::zero() },
         }
     }
 }
diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs
index 9dac8e09ad2..c3e9815f228 100644
--- a/src/libserialize/lib.rs
+++ b/src/libserialize/lib.rs
@@ -37,6 +37,7 @@ Core encoding and decoding interfaces.
 #![feature(rustc_private)]
 #![feature(std_misc)]
 #![feature(unicode)]
+#![cfg_attr(test, feature(test))]
 
 // test harness access
 #[cfg(test)] extern crate test;
diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs
index 43d7db6cbbf..bbc3f80dd86 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(feature = "oldstuff", since = "1.0.0",
+#[unstable(feature = "io")]
+#[deprecated(since = "1.0.0",
              reason = "use the Vec<u8> Writer implementation directly")]
 #[derive(Clone)]
 pub struct MemWriter {
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 025552e6094..643e10f0f29 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -121,6 +121,7 @@
 #![feature(collections)]
 #![feature(rand)]
 #![feature(hash)]
+#![cfg_attr(test, feature(test))]
 
 // Don't link to std. We are std.
 #![no_std]
diff --git a/src/libstd/num/int.rs b/src/libstd/num/int.rs
index 2bf9f9b025d..669952eee39 100644
--- a/src/libstd/num/int.rs
+++ b/src/libstd/num/int.rs
@@ -14,7 +14,8 @@
 //! alpha cycle along with the development of clearer conventions
 //! around integer types.
 
-#![deprecated(feature = "oldstuff", since = "1.0.0", reason = "replaced by isize")]
+#![unstable(feature = "std_misc")]
+#![deprecated(since = "1.0.0", reason = "replaced by isize")]
 
 pub use core::int::{BITS, BYTES, MIN, MAX};
 
diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs
index b73882c76c1..78ccaeef7bc 100644
--- a/src/libstd/num/mod.rs
+++ b/src/libstd/num/mod.rs
@@ -79,32 +79,39 @@ pub trait Float
     // FIXME (#5527): These should be associated constants
 
     /// Returns the number of binary digits of mantissa that this type supports.
-    #[deprecated(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "std_misc")]
+    #[deprecated(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(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "std_misc")]
+    #[deprecated(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(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "std_misc")]
+    #[deprecated(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(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "std_misc")]
+    #[deprecated(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(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "std_misc")]
+    #[deprecated(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(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "std_misc")]
+    #[deprecated(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(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "std_misc")]
+    #[deprecated(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;
 
diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs
index 58685b05981..c7b491381f3 100644
--- a/src/libstd/num/uint.rs
+++ b/src/libstd/num/uint.rs
@@ -14,7 +14,8 @@
 //! alpha cycle along with the development of clearer conventions
 //! around integer types.
 
-#![deprecated(feature = "oldstuff", since = "1.0.0", reason = "replaced by usize")]
+#![unstable(feature = "std_misc")]
+#![deprecated(since = "1.0.0", reason = "replaced by usize")]
 
 pub use core::uint::{BITS, BYTES, MIN, MAX};
 
diff --git a/src/libstd/prelude/mod.rs b/src/libstd/prelude/mod.rs
index 7e53f45422d..f5cf4447652 100644
--- a/src/libstd/prelude/mod.rs
+++ b/src/libstd/prelude/mod.rs
@@ -37,5 +37,4 @@
 
 #![stable(feature = "grandfathered", since = "1.0.0")]
 
-#[stable(feature = "grandfathered", since = "1.0.0")]
 pub mod v1;
diff --git a/src/libstd/sync/poison.rs b/src/libstd/sync/poison.rs
index d2362eefcf1..f5bb7a56d77 100644
--- a/src/libstd/sync/poison.rs
+++ b/src/libstd/sync/poison.rs
@@ -105,7 +105,8 @@ 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(feature = "oldstuff", since = "1.0.0", reason = "renamed to into_inner")]
+    #[unstable(feature = "std_misc")]
+    #[deprecated(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
diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs
index 94e5d19d61b..bb8f73214d0 100644
--- a/src/libstd/thread_local/mod.rs
+++ b/src/libstd/thread_local/mod.rs
@@ -319,7 +319,8 @@ impl<T: 'static> Key<T> {
     }
 
     /// Deprecated
-    #[deprecated(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "std_misc")]
+    #[deprecated(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/libsyntax/attr.rs b/src/libsyntax/attr.rs
index ff1dc5d0c35..d63370b41f5 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -351,13 +351,15 @@ pub struct Stability {
     pub level: StabilityLevel,
     pub feature: InternedString,
     pub since: Option<InternedString>,
+    pub deprecated_since: Option<InternedString>,
+    // The reason for the current stability level. If deprecated, the
+    // reason for deprecation.
     pub reason: Option<InternedString>,
 }
 
 /// The available stability levels.
 #[derive(RustcEncodable,RustcDecodable,PartialEq,PartialOrd,Clone,Show,Copy)]
 pub enum StabilityLevel {
-    Deprecated,
     Unstable,
     Stable,
 }
@@ -368,18 +370,24 @@ impl fmt::String for StabilityLevel {
     }
 }
 
-pub fn find_stability_generic<'a,
+fn find_stability_generic<'a,
                               AM: AttrMetaMethods,
                               I: Iterator<Item=&'a AM>>
-                             (diagnostic: &SpanHandler, mut attrs: I)
-                             -> Option<(Stability, &'a AM)> {
-    for attr in attrs {
-        let level = match attr.name().get() {
-            "deprecated" => Deprecated,
-            "unstable" => Unstable,
-            "stable" => Stable,
-            _ => continue // not a stability level
-        };
+                             (diagnostic: &SpanHandler, mut attrs: I, item_sp: Span)
+                             -> (Option<Stability>, Vec<&'a AM>) {
+
+    let mut stab: Option<Stability> = None;
+    let mut deprecated: Option<(InternedString, Option<InternedString>)> = None;
+    let mut used_attrs: Vec<&'a AM> = vec![];
+
+    'outer: for attr in attrs {
+        let tag = attr.name();
+        let tag = tag.get();
+        if tag != "deprecated" && tag != "unstable" && tag != "stable" {
+            continue // not a stability level
+        }
+
+        used_attrs.push(attr);
 
         let (feature, since, reason) = match attr.meta_item_list() {
             Some(metas) => {
@@ -392,6 +400,7 @@ pub fn find_stability_generic<'a,
                             Some(v) => feature = Some(v),
                             None => {
                                 diagnostic.span_err(meta.span, "incorrect meta item");
+                                continue 'outer;
                             }
                         }
                     }
@@ -400,6 +409,7 @@ pub fn find_stability_generic<'a,
                             Some(v) => since = Some(v),
                             None => {
                                 diagnostic.span_err(meta.span, "incorrect meta item");
+                                continue 'outer;
                             }
                         }
                     }
@@ -408,6 +418,7 @@ pub fn find_stability_generic<'a,
                             Some(v) => reason = Some(v),
                             None => {
                                 diagnostic.span_err(meta.span, "incorrect meta item");
+                                continue 'outer;
                             }
                         }
                     }
@@ -416,34 +427,71 @@ pub fn find_stability_generic<'a,
             }
             None => {
                 diagnostic.span_err(attr.span(), "incorrect stability attribute type");
-                (None, None, None)
+                continue
             }
         };
 
-        if feature == None {
+        // Deprecated tags don't require feature names
+        if feature == None && tag != "deprecated" {
             diagnostic.span_err(attr.span(), "missing 'feature'");
         }
 
-        if since == None && level != Unstable {
+        // Unstable tags don't require a version
+        if since == None && tag != "unstable" {
             diagnostic.span_err(attr.span(), "missing 'since'");
         }
 
-        return Some((Stability {
-            level: level,
-            feature: feature.unwrap_or(intern_and_get_ident("bogus")),
-            since: since,
-            reason: reason,
-        }, attr));
+        if tag == "unstable" || tag == "stable" {
+            if stab.is_some() {
+                diagnostic.span_err(item_sp, "multiple stability levels");
+            }
+
+            let level = match tag {
+                "unstable" => Unstable,
+                "stable" => Stable,
+                _ => unreachable!()
+            };
+
+            stab = Some(Stability {
+                level: level,
+                feature: feature.unwrap_or(intern_and_get_ident("bogus")),
+                since: since,
+                deprecated_since: None,
+                reason: reason
+            });
+        } else { // "deprecated"
+            if deprecated.is_some() {
+                diagnostic.span_err(item_sp, "multiple deprecated attributes");
+            }
+
+            deprecated = Some((since.unwrap_or(intern_and_get_ident("bogus")), reason));
+        }
+    }
+
+    // Merge the deprecation info into the stability info
+    if deprecated.is_some() {
+        match stab {
+            Some(ref mut s) => {
+                let (since, reason) = deprecated.unwrap();
+                s.deprecated_since = Some(since);
+                s.reason = reason;
+            }
+            None => {
+                diagnostic.span_err(item_sp, "deprecated attribute must be paired with \
+                                              either stable or unstable attribute");
+            }
+        }
     }
-    None
+
+    (stab, used_attrs)
 }
 
 /// Find the first stability attribute. `None` if none exists.
-pub fn find_stability(diagnostic: &SpanHandler, attrs: &[Attribute]) -> Option<Stability> {
-    find_stability_generic(diagnostic, attrs.iter()).map(|(s, attr)| {
-        mark_used(attr);
-        s
-    })
+pub fn find_stability(diagnostic: &SpanHandler, attrs: &[Attribute],
+                      item_sp: Span) -> Option<Stability> {
+    let (s, used) = find_stability_generic(diagnostic, attrs.iter(), item_sp);
+    for used in used.into_iter() { mark_used(used) }
+    return s;
 }
 
 pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[P<MetaItem>]) {
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index cd04332b47f..bca7131fdb7 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -568,7 +568,8 @@ impl<'a> ExtCtxt<'a> {
         }
     }
 
-    #[deprecated(feature = "oldstuff", since = "1.0.0",
+    #[unstable(feature = "rustc_private")]
+    #[deprecated(since = "1.0.0",
                  reason = "Replaced with `expander().fold_expr()`")]
     pub fn expand_expr(&mut self, e: P<ast::Expr>) -> P<ast::Expr> {
         self.expander().fold_expr(e)
diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs
index 342fed1653d..22f2fb36fc8 100644
--- a/src/libsyntax/util/small_vector.rs
+++ b/src/libsyntax/util/small_vector.rs
@@ -112,7 +112,8 @@ impl<T> SmallVector<T> {
     }
 
     /// Deprecated: use `into_iter`.
-    #[deprecated(feature = "oldstuff", since = "1.0.0", reason = "use into_iter")]
+    #[unstable(feature = "rustc_private")]
+    #[deprecated(since = "1.0.0", reason = "use into_iter")]
     pub fn move_iter(self) -> IntoIter<T> {
         self.into_iter()
     }
diff --git a/src/test/auxiliary/inherited_stability.rs b/src/test/auxiliary/inherited_stability.rs
index 1fb3e4656f8..bb2a5d796c2 100644
--- a/src/test/auxiliary/inherited_stability.rs
+++ b/src/test/auxiliary/inherited_stability.rs
@@ -28,7 +28,8 @@ pub mod stable_mod {
 
 #[unstable(feature = "test_feature")]
 pub mod unstable_mod {
-    #[deprecated(feature = "test_feature", since = "1.0.0")]
+    #[stable(feature = "test_feature", since = "1.0.0")]
+    #[deprecated(since = "1.0.0")]
     pub fn deprecated() {}
 
     pub fn unstable() {}
diff --git a/src/test/auxiliary/lint_output_format.rs b/src/test/auxiliary/lint_output_format.rs
index c6b1579cecb..1977e2aad28 100755
--- a/src/test/auxiliary/lint_output_format.rs
+++ b/src/test/auxiliary/lint_output_format.rs
@@ -14,7 +14,8 @@
 #![staged_api]
 #![unstable(feature = "test_feature")]
 
-#[deprecated(feature = "oldstuff", since = "1.0.0")]
+#[stable(feature = "test_feature", since = "1.0.0")]
+#[deprecated(since = "1.0.0")]
 pub fn foo() -> uint {
     20
 }
diff --git a/src/test/auxiliary/lint_stability.rs b/src/test/auxiliary/lint_stability.rs
index 0f2749b0b19..f534d4bbb7e 100644
--- a/src/test/auxiliary/lint_stability.rs
+++ b/src/test/auxiliary/lint_stability.rs
@@ -12,12 +12,21 @@
 #![feature(staged_api)]
 #![staged_api]
 
-#[deprecated(feature = "oldstuff", since = "1.0.0")]
+#[stable(feature = "test_feature", since = "1.0.0")]
+#[deprecated(since = "1.0.0")]
 pub fn deprecated() {}
-#[deprecated(feature = "oldstuff", since = "1.0.0", reason = "text")]
+#[stable(feature = "test_feature", since = "1.0.0")]
+#[deprecated(since = "1.0.0", reason = "text")]
 pub fn deprecated_text() {}
 
 #[unstable(feature = "test_feature")]
+#[deprecated(since = "1.0.0")]
+pub fn deprecated_unstable() {}
+#[unstable(feature = "test_feature")]
+#[deprecated(since = "1.0.0", reason = "text")]
+pub fn deprecated_unstable_text() {}
+
+#[unstable(feature = "test_feature")]
 pub fn unstable() {}
 #[unstable(feature = "test_feature", reason = "text")]
 pub fn unstable_text() {}
@@ -33,12 +42,21 @@ pub fn stable_text() {}
 pub struct MethodTester;
 
 impl MethodTester {
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[stable(feature = "test_feature", since = "1.0.0")]
+    #[deprecated(since = "1.0.0")]
     pub fn method_deprecated(&self) {}
-    #[deprecated(feature = "oldstuff", since = "1.0.0", reason = "text")]
+    #[stable(feature = "test_feature", since = "1.0.0")]
+    #[deprecated(since = "1.0.0", reason = "text")]
     pub fn method_deprecated_text(&self) {}
 
     #[unstable(feature = "test_feature")]
+    #[deprecated(since = "1.0.0")]
+    pub fn method_deprecated_unstable(&self) {}
+    #[unstable(feature = "test_feature")]
+    #[deprecated(since = "1.0.0", reason = "text")]
+    pub fn method_deprecated_unstable_text(&self) {}
+
+    #[unstable(feature = "test_feature")]
     pub fn method_unstable(&self) {}
     #[unstable(feature = "test_feature", reason = "text")]
     pub fn method_unstable_text(&self) {}
@@ -62,12 +80,21 @@ impl MethodTester {
 }
 
 pub trait Trait {
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[stable(feature = "test_feature", since = "1.0.0")]
+    #[deprecated(since = "1.0.0")]
     fn trait_deprecated(&self) {}
-    #[deprecated(feature = "oldstuff", since = "1.0.0", reason = "text")]
+    #[stable(feature = "test_feature", since = "1.0.0")]
+    #[deprecated(since = "1.0.0", reason = "text")]
     fn trait_deprecated_text(&self) {}
 
     #[unstable(feature = "test_feature")]
+    #[deprecated(since = "1.0.0")]
+    fn trait_deprecated_unstable(&self) {}
+    #[unstable(feature = "test_feature")]
+    #[deprecated(since = "1.0.0", reason = "text")]
+    fn trait_deprecated_unstable_text(&self) {}
+
+    #[unstable(feature = "test_feature")]
     fn trait_unstable(&self) {}
     #[unstable(feature = "test_feature", reason = "text")]
     fn trait_unstable_text(&self) {}
@@ -95,26 +122,38 @@ impl Trait for MethodTester {}
 #[unstable(feature = "test_feature")]
 pub trait UnstableTrait {}
 
-#[deprecated(feature = "oldstuff", since = "1.0.0")]
+#[stable(feature = "test_feature", since = "1.0.0")]
+#[deprecated(since = "1.0.0")]
 pub struct DeprecatedStruct { pub i: int }
 #[unstable(feature = "test_feature")]
+#[deprecated(since = "1.0.0")]
+pub struct DeprecatedUnstableStruct { pub i: int }
+#[unstable(feature = "test_feature")]
 pub struct UnstableStruct { pub i: int }
 pub struct UnmarkedStruct { pub i: int }
 #[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct StableStruct { pub i: int }
 
-#[deprecated(feature = "oldstuff", since = "1.0.0")]
+#[stable(feature = "test_feature", since = "1.0.0")]
+#[deprecated(since = "1.0.0")]
 pub struct DeprecatedUnitStruct;
 #[unstable(feature = "test_feature")]
+#[deprecated(since = "1.0.0")]
+pub struct DeprecatedUnstableUnitStruct;
+#[unstable(feature = "test_feature")]
 pub struct UnstableUnitStruct;
 pub struct UnmarkedUnitStruct;
 #[stable(feature = "grandfathered", since = "1.0.0")]
 pub struct StableUnitStruct;
 
 pub enum Enum {
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[stable(feature = "test_feature", since = "1.0.0")]
+    #[deprecated(since = "1.0.0")]
     DeprecatedVariant,
     #[unstable(feature = "test_feature")]
+    #[deprecated(since = "1.0.0")]
+    DeprecatedUnstableVariant,
+    #[unstable(feature = "test_feature")]
     UnstableVariant,
 
     UnmarkedVariant,
@@ -122,9 +161,13 @@ pub enum Enum {
     StableVariant,
 }
 
-#[deprecated(feature = "oldstuff", since = "1.0.0")]
+#[stable(feature = "test_feature", since = "1.0.0")]
+#[deprecated(since = "1.0.0")]
 pub struct DeprecatedTupleStruct(pub int);
 #[unstable(feature = "test_feature")]
+#[deprecated(since = "1.0.0")]
+pub struct DeprecatedUnstableTupleStruct(pub int);
+#[unstable(feature = "test_feature")]
 pub struct UnstableTupleStruct(pub int);
 pub struct UnmarkedTupleStruct(pub int);
 #[stable(feature = "grandfathered", since = "1.0.0")]
diff --git a/src/test/compile-fail/issue-17337.rs b/src/test/compile-fail/issue-17337.rs
index 92a35ef48c5..ff640793afe 100644
--- a/src/test/compile-fail/issue-17337.rs
+++ b/src/test/compile-fail/issue-17337.rs
@@ -15,7 +15,8 @@
 struct Foo;
 
 impl Foo {
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "test_feature")]
+    #[deprecated(since = "1.0.0")]
     fn foo(self) {}
 }
 
diff --git a/src/test/compile-fail/lint-stability.rs b/src/test/compile-fail/lint-stability.rs
index e89151aa746..1d5399b93f9 100644
--- a/src/test/compile-fail/lint-stability.rs
+++ b/src/test/compile-fail/lint-stability.rs
@@ -39,6 +39,20 @@ mod cross_crate {
         foo.method_deprecated_text(); //~ ERROR use of deprecated item: text
         foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
 
+        deprecated_unstable(); //~ ERROR use of deprecated item
+        //~^ WARNING use of unstable library feature
+        foo.method_deprecated_unstable(); //~ ERROR use of deprecated item
+        //~^ WARNING use of unstable library feature
+        foo.trait_deprecated_unstable(); //~ ERROR use of deprecated item
+        //~^ WARNING use of unstable library feature
+
+        deprecated_unstable_text(); //~ ERROR use of deprecated item: text
+        //~^ WARNING use of unstable library feature
+        foo.method_deprecated_unstable_text(); //~ ERROR use of deprecated item: text
+        //~^ WARNING use of unstable library feature
+        foo.trait_deprecated_unstable_text(); //~ ERROR use of deprecated item: text
+        //~^ WARNING use of unstable library feature
+
         unstable(); //~ WARNING use of unstable library feature
         foo.method_unstable(); //~ WARNING use of unstable library feature
         foo.trait_unstable(); //~ WARNING use of unstable library feature
@@ -60,21 +74,29 @@ mod cross_crate {
         foo.trait_stable_text();
 
         let _ = DeprecatedStruct { i: 0 }; //~ ERROR use of deprecated item
+        let _ = DeprecatedUnstableStruct { i: 0 }; //~ ERROR use of deprecated item
+        //~^ WARNING use of unstable library feature
         let _ = UnstableStruct { i: 0 }; //~ WARNING use of unstable library feature
         let _ = UnmarkedStruct { i: 0 }; //~ ERROR use of unmarked library feature
         let _ = StableStruct { i: 0 };
 
         let _ = DeprecatedUnitStruct; //~ ERROR use of deprecated item
+        let _ = DeprecatedUnstableUnitStruct; //~ ERROR use of deprecated item
+        //~^ WARNING use of unstable library feature
         let _ = UnstableUnitStruct; //~ WARNING use of unstable library feature
         let _ = UnmarkedUnitStruct; //~ ERROR use of unmarked library feature
         let _ = StableUnitStruct;
 
         let _ = Enum::DeprecatedVariant; //~ ERROR use of deprecated item
+        let _ = Enum::DeprecatedUnstableVariant; //~ ERROR use of deprecated item
+        //~^ WARNING use of unstable library feature
         let _ = Enum::UnstableVariant; //~ WARNING use of unstable library feature
         let _ = Enum::UnmarkedVariant; //~ ERROR use of unmarked library feature
         let _ = Enum::StableVariant;
 
         let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated item
+        let _ = DeprecatedUnstableTupleStruct (1); //~ ERROR use of deprecated item
+        //~^ WARNING use of unstable library feature
         let _ = UnstableTupleStruct (1); //~ WARNING use of unstable library feature
         let _ = UnmarkedTupleStruct (1); //~ ERROR use of unmarked library feature
         let _ = StableTupleStruct (1);
@@ -86,6 +108,8 @@ mod cross_crate {
         // on macros themselves are not yet linted.
         macro_test!();
         macro_test_arg!(deprecated_text()); //~ ERROR use of deprecated item: text
+        macro_test_arg!(deprecated_unstable_text()); //~ ERROR use of deprecated item: text
+        //~^ WARNING use of unstable library feature
         macro_test_arg!(macro_test_arg!(deprecated_text())); //~ ERROR use of deprecated item: text
         macro_test_arg_nested!(deprecated_text);
     }
@@ -93,6 +117,10 @@ mod cross_crate {
     fn test_method_param<F: Trait>(foo: F) {
         foo.trait_deprecated(); //~ ERROR use of deprecated item
         foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
+        foo.trait_deprecated_unstable(); //~ ERROR use of deprecated item
+        //~^ WARNING use of unstable library feature
+        foo.trait_deprecated_unstable_text(); //~ ERROR use of deprecated item: text
+        //~^ WARNING use of unstable library feature
         foo.trait_unstable(); //~ WARNING use of unstable library feature
         foo.trait_unstable_text(); //~ WARNING use of unstable library feature 'test_feature': text
         foo.trait_unmarked(); //~ ERROR use of unmarked library feature
@@ -102,6 +130,10 @@ mod cross_crate {
     fn test_method_object(foo: &Trait) {
         foo.trait_deprecated(); //~ ERROR use of deprecated item
         foo.trait_deprecated_text(); //~ ERROR use of deprecated item: text
+        foo.trait_deprecated_unstable(); //~ ERROR use of deprecated item
+        //~^ WARNING use of unstable library feature
+        foo.trait_deprecated_unstable_text(); //~ ERROR use of deprecated item: text
+        //~^ WARNING use of unstable library feature
         foo.trait_unstable(); //~ WARNING use of unstable library feature
         foo.trait_unstable_text(); //~ WARNING use of unstable library feature 'test_feature': text
         foo.trait_unmarked(); //~ ERROR use of unmarked library feature
@@ -139,9 +171,11 @@ mod inheritance {
 }
 
 mod this_crate {
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "test_feature")]
+    #[deprecated(since = "1.0.0")]
     pub fn deprecated() {}
-    #[deprecated(feature = "oldstuff", since = "1.0.0", reason = "text")]
+    #[unstable(feature = "test_feature")]
+    #[deprecated(since = "1.0.0", reason = "text")]
     pub fn deprecated_text() {}
 
     #[unstable(feature = "test_feature")]
@@ -160,9 +194,11 @@ mod this_crate {
     pub struct MethodTester;
 
     impl MethodTester {
-        #[deprecated(feature = "oldstuff", since = "1.0.0")]
+        #[unstable(feature = "test_feature")]
+        #[deprecated(since = "1.0.0")]
         pub fn method_deprecated(&self) {}
-        #[deprecated(feature = "oldstuff", since = "1.0.0", reason = "text")]
+        #[unstable(feature = "test_feature")]
+        #[deprecated(since = "1.0.0", reason = "text")]
         pub fn method_deprecated_text(&self) {}
 
         #[unstable(feature = "test_feature")]
@@ -179,9 +215,11 @@ mod this_crate {
     }
 
     pub trait Trait {
-        #[deprecated(feature = "oldstuff", since = "1.0.0")]
+        #[unstable(feature = "test_feature")]
+        #[deprecated(since = "1.0.0")]
         fn trait_deprecated(&self) {}
-        #[deprecated(feature = "oldstuff", since = "1.0.0", reason = "text")]
+        #[unstable(feature = "test_feature")]
+        #[deprecated(since = "1.0.0", reason = "text")]
         fn trait_deprecated_text(&self) {}
 
         #[unstable(feature = "test_feature")]
@@ -199,7 +237,8 @@ mod this_crate {
 
     impl Trait for MethodTester {}
 
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "test_feature")]
+    #[deprecated(since = "1.0.0")]
     pub struct DeprecatedStruct { i: isize }
     #[unstable(feature = "test_feature")]
     pub struct UnstableStruct { i: isize }
@@ -207,7 +246,8 @@ mod this_crate {
     #[stable(feature = "grandfathered", since = "1.0.0")]
     pub struct StableStruct { i: isize }
 
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "test_feature")]
+    #[deprecated(since = "1.0.0")]
     pub struct DeprecatedUnitStruct;
     #[unstable(feature = "test_feature")]
     pub struct UnstableUnitStruct;
@@ -216,7 +256,8 @@ mod this_crate {
     pub struct StableUnitStruct;
 
     pub enum Enum {
-        #[deprecated(feature = "oldstuff", since = "1.0.0")]
+        #[unstable(feature = "test_feature")]
+        #[deprecated(since = "1.0.0")]
         DeprecatedVariant,
         #[unstable(feature = "test_feature")]
         UnstableVariant,
@@ -226,7 +267,8 @@ mod this_crate {
         StableVariant,
     }
 
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "test_feature")]
+    #[deprecated(since = "1.0.0")]
     pub struct DeprecatedTupleStruct(isize);
     #[unstable(feature = "test_feature")]
     pub struct UnstableTupleStruct(isize);
@@ -308,21 +350,24 @@ mod this_crate {
         foo.trait_stable();
     }
 
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "test_feature")]
+    #[deprecated(since = "1.0.0")]
     fn test_fn_body() {
         fn fn_in_body() {}
         fn_in_body();
     }
 
     impl MethodTester {
-        #[deprecated(feature = "oldstuff", since = "1.0.0")]
+        #[unstable(feature = "test_feature")]
+        #[deprecated(since = "1.0.0")]
         fn test_method_body(&self) {
             fn fn_in_body() {}
             fn_in_body();
         }
     }
 
-    #[deprecated(feature = "oldstuff", since = "1.0.0")]
+    #[unstable(feature = "test_feature")]
+    #[deprecated(since = "1.0.0")]
     pub trait DeprecatedTrait {}
 
     struct S;
diff --git a/src/test/compile-fail/stability-attribute-sanity.rs b/src/test/compile-fail/stability-attribute-sanity.rs
new file mode 100644
index 00000000000..dcbb1880b10
--- /dev/null
+++ b/src/test/compile-fail/stability-attribute-sanity.rs
@@ -0,0 +1,95 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Various checks that stability attributes are used correctly, per RFC 507
+
+#![feature(staged_api)]
+#![staged_api]
+
+mod bogus_attribute_types_1 {
+    #[stable(feature = "a", since = "a", reason)] //~ ERROR incorrect meta item
+    fn f1() { }
+
+    #[stable(feature = "a", since, reason = "a")] //~ ERROR incorrect meta item
+    fn f2() { }
+
+    #[stable(feature, since = "a", reason = "a")] //~ ERROR incorrect meta item
+    fn f3() { }
+
+    #[stable(feature = "a", since = "a", reason(b))] //~ ERROR incorrect meta item
+    fn f4() { }
+
+    #[stable(feature = "a", since(b), reason = "a")] //~ ERROR incorrect meta item
+    fn f5() { }
+
+    #[stable(feature(b), since = "a", reason = "a")] //~ ERROR incorrect meta item
+    fn f6() { }
+}
+
+mod bogus_attribute_types_2 {
+    #[unstable] //~ ERROR incorrect stability attribute type
+    fn f1() { }
+
+    #[unstable = "a"] //~ ERROR incorrect stability attribute type
+    fn f2() { }
+
+    #[stable] //~ ERROR incorrect stability attribute type
+    fn f3() { }
+
+    #[stable = "a"] //~ ERROR incorrect stability attribute type
+    fn f4() { }
+
+    #[stable(feature = "a", since = "b")]
+    #[deprecated] //~ ERROR incorrect stability attribute type
+    fn f5() { }
+
+    #[stable(feature = "a", since = "b")]
+    #[deprecated = "a"] //~ ERROR incorrect stability attribute type
+    fn f6() { }
+}
+
+mod missing_feature_names {
+    #[unstable(since = "a")] //~ ERROR missing 'feature'
+    fn f1() { }
+
+    #[stable(since = "a")] //~ ERROR missing 'feature'
+    fn f2() { }
+}
+
+mod missing_version {
+    #[stable(feature = "a")] //~ ERROR missing 'since'
+    fn f1() { }
+
+    #[stable(feature = "a", since = "b")]
+    #[deprecated(reason = "a")] //~ ERROR missing 'since'
+    fn f2() { }
+}
+
+#[unstable(feature = "a", since = "b")]
+#[stable(feature = "a", since = "b")]
+fn multiple1() { } //~ ERROR multiple stability levels
+
+#[unstable(feature = "a", since = "b")]
+#[unstable(feature = "a", since = "b")]
+fn multiple2() { } //~ ERROR multiple stability levels
+
+#[stable(feature = "a", since = "b")]
+#[stable(feature = "a", since = "b")]
+fn multiple3() { } //~ ERROR multiple stability levels
+
+#[stable(feature = "a", since = "b")]
+#[deprecated(since = "b")]
+#[deprecated(since = "b")]
+fn multiple4() { } //~ ERROR multiple deprecated attributes
+
+#[deprecated(since = "a")]
+fn deprecated_without_unstable_or_stable() { } //~ ERROR deprecated attribute must be paired
+
+fn main() { }