From 9758c488a94e77cc8a110a6783a99cf5b91326db Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 22 Jan 2015 12:33:46 -0800 Subject: 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 --- src/libsyntax/attr.rs | 100 +++++++++++++++++++++++++++---------- src/libsyntax/ext/base.rs | 3 +- src/libsyntax/util/small_vector.rs | 3 +- 3 files changed, 78 insertions(+), 28 deletions(-) (limited to 'src/libsyntax') 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, + pub deprecated_since: Option, + // The reason for the current stability level. If deprecated, the + // reason for deprecation. pub reason: Option, } /// 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> - (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, Vec<&'a AM>) { + + let mut stab: Option = None; + let mut deprecated: Option<(InternedString, Option)> = 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 { - 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 { + 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]) { 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) -> P { 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 SmallVector { } /// 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 { self.into_iter() } -- cgit 1.4.1-3-g733a5