diff options
| author | Alexis Beingessner <a.beingessner@gmail.com> | 2015-06-11 17:18:46 -0700 |
|---|---|---|
| committer | Alexis Beingessner <a.beingessner@gmail.com> | 2015-06-11 17:18:46 -0700 |
| commit | 2962b2681fd9dd4c91f27c4b061d9a2dc15ced02 (patch) | |
| tree | ba6ab87d393257fe03210b12620fff499183af0a | |
| parent | 5779fff5436c13369d655b76b7d81aed534776dc (diff) | |
| download | rust-2962b2681fd9dd4c91f27c4b061d9a2dc15ced02.tar.gz rust-2962b2681fd9dd4c91f27c4b061d9a2dc15ced02.zip | |
validate stability against deprecation version
| -rw-r--r-- | src/librustc/middle/stability.rs | 39 | ||||
| -rw-r--r-- | src/libsyntax/attr.rs | 6 | ||||
| -rw-r--r-- | src/test/compile-fail/stability-attribute-sanity.rs | 1 |
3 files changed, 43 insertions, 3 deletions
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 5d092167d5a..26efa5b4389 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -31,6 +31,7 @@ use util::nodemap::{DefIdMap, FnvHashSet, FnvHashMap}; use util::ppaux::Repr; use std::mem::replace; +use std::cmp::Ordering; /// A stability index, giving the stability level for items and methods. pub struct Index<'tcx> { @@ -73,6 +74,44 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> { } let stab = self.tcx.intern_stability(stab); + + // Check if deprecated_since < stable_since. If it is, + // this is *almost surely* an accident. + let deprecated_predates_stable = match (stab.deprecated_since.as_ref(), + stab.since.as_ref()) { + (Some(dep_since), Some(stab_since)) => { + // explicit version of iter::order::lt to handle parse errors properly + let mut is_less = false; + for (dep_v, stab_v) in dep_since.split(".").zip(stab_since.split(".")) { + match (dep_v.parse::<u64>(), stab_v.parse::<u64>()) { + (Ok(dep_v), Ok(stab_v)) => match dep_v.cmp(&stab_v) { + Ordering::Less => { + is_less = true; + break; + } + Ordering::Equal => { continue; } + Ordering::Greater => { break; } + }, + _ => { + self.tcx.sess.span_err(item_sp, + "Invalid stability or deprecation version found"); + // act like it isn't less because the question is now + // nonsensical, and this makes us not do anything else + // interesting. + break; + } + } + } + is_less + }, + _ => false, + }; + + if deprecated_predates_stable { + self.tcx.sess.span_err(item_sp, + "An API can't be stabilized after it is deprecated"); + } + self.index.map.insert(local_def(id), Some(stab)); // Don't inherit #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 3c4c4d70343..44f84ec7594 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -397,7 +397,7 @@ fn find_stability_generic<'a, -> (Option<Stability>, Vec<&'a AM>) { let mut stab: Option<Stability> = None; - let mut deprecated: Option<(InternedString, Option<InternedString>)> = None; + let mut deprecated: Option<(Option<InternedString>, Option<InternedString>)> = None; let mut used_attrs: Vec<&'a AM> = vec![]; 'outer: for attr in attrs { @@ -484,7 +484,7 @@ fn find_stability_generic<'a, diagnostic.span_err(item_sp, "multiple deprecated attributes"); } - deprecated = Some((since.unwrap_or(intern_and_get_ident("bogus")), reason)); + deprecated = Some((since, reason)); } } @@ -493,7 +493,7 @@ fn find_stability_generic<'a, match stab { Some(ref mut s) => { let (since, reason) = deprecated.unwrap(); - s.deprecated_since = Some(since); + s.deprecated_since = since; s.reason = reason; } None => { diff --git a/src/test/compile-fail/stability-attribute-sanity.rs b/src/test/compile-fail/stability-attribute-sanity.rs index dcbb1880b10..f0597d57b79 100644 --- a/src/test/compile-fail/stability-attribute-sanity.rs +++ b/src/test/compile-fail/stability-attribute-sanity.rs @@ -88,6 +88,7 @@ fn multiple3() { } //~ ERROR multiple stability levels #[deprecated(since = "b")] #[deprecated(since = "b")] fn multiple4() { } //~ ERROR multiple deprecated attributes +//~^ ERROR Invalid stability or deprecation version found #[deprecated(since = "a")] fn deprecated_without_unstable_or_stable() { } //~ ERROR deprecated attribute must be paired |
