diff options
| author | Brian Anderson <banderson@mozilla.com> | 2015-01-22 12:33:46 -0800 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2015-01-23 15:50:03 -0800 |
| commit | 9758c488a94e77cc8a110a6783a99cf5b91326db (patch) | |
| tree | ca5f2436cb4b9dc39aa7f525cf4a5fc9288d0ac7 /src/libsyntax | |
| parent | cd6d9eab5d75584edfcae4ffdef8b0836db80c1e (diff) | |
| download | rust-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
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/attr.rs | 100 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/util/small_vector.rs | 3 |
3 files changed, 78 insertions, 28 deletions
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() } |
