Auto merge of #30206 - petrochenkov:newdepr, r=brson

Closes https://github.com/rust-lang/rust/issues/29935

The attributes `deprecated` and `rustc_deprecated` are completely independent in this implementation and it leads to some noticeable code duplication. Representing `deprecated` as
```
Stability {
    level: Stable { since: "" },
    feature: "",
    depr: Some(Deprecation),
}
```
or, contrariwise, splitting rustc_deprecation from stability makes most of the duplication go away.
I can do this refactoring, but before doing it I must be sure, that further divergence of `deprecated` and `rustc_deprecated` is certainly not a goal.

cc @llogiq
This commit is contained in:
bors
2015-12-16 08:15:23 +00:00
26 changed files with 1003 additions and 137 deletions

View File

@@ -398,7 +398,7 @@ pub fn cfg_matches<T: CfgDiag>(cfgs: &[P<MetaItem>],
pub struct Stability {
pub level: StabilityLevel,
pub feature: InternedString,
pub depr: Option<Deprecation>,
pub rustc_depr: Option<RustcDeprecation>,
}
/// The available stability levels.
@@ -410,11 +410,17 @@ pub enum StabilityLevel {
}
#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
pub struct Deprecation {
pub struct RustcDeprecation {
pub since: InternedString,
pub reason: InternedString,
}
#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)]
pub struct Deprecation {
pub since: Option<InternedString>,
pub note: Option<InternedString>,
}
impl StabilityLevel {
pub fn is_unstable(&self) -> bool { if let Unstable {..} = *self { true } else { false }}
pub fn is_stable(&self) -> bool { if let Stable {..} = *self { true } else { false }}
@@ -427,7 +433,7 @@ fn find_stability_generic<'a, I>(diagnostic: &SpanHandler,
where I: Iterator<Item = &'a Attribute>
{
let mut stab: Option<Stability> = None;
let mut depr: Option<Deprecation> = None;
let mut rustc_depr: Option<RustcDeprecation> = None;
'outer: for attr in attrs_iter {
let tag = attr.name();
@@ -456,7 +462,7 @@ fn find_stability_generic<'a, I>(diagnostic: &SpanHandler,
match tag {
"rustc_deprecated" => {
if depr.is_some() {
if rustc_depr.is_some() {
diagnostic.span_err(item_sp, "multiple rustc_deprecated attributes");
break
}
@@ -477,7 +483,7 @@ fn find_stability_generic<'a, I>(diagnostic: &SpanHandler,
match (since, reason) {
(Some(since), Some(reason)) => {
depr = Some(Deprecation {
rustc_depr = Some(RustcDeprecation {
since: since,
reason: reason,
})
@@ -529,7 +535,7 @@ fn find_stability_generic<'a, I>(diagnostic: &SpanHandler,
}
},
feature: feature,
depr: None,
rustc_depr: None,
})
}
(None, _, _) => {
@@ -569,7 +575,7 @@ fn find_stability_generic<'a, I>(diagnostic: &SpanHandler,
since: since,
},
feature: feature,
depr: None,
rustc_depr: None,
})
}
(None, _) => {
@@ -591,12 +597,12 @@ fn find_stability_generic<'a, I>(diagnostic: &SpanHandler,
}
// Merge the deprecation info into the stability info
if let Some(depr) = depr {
if let Some(rustc_depr) = rustc_depr {
if let Some(ref mut stab) = stab {
if let Unstable {reason: ref mut reason @ None, ..} = stab.level {
*reason = Some(depr.reason.clone())
*reason = Some(rustc_depr.reason.clone())
}
stab.depr = Some(depr);
stab.rustc_depr = Some(rustc_depr);
} else {
diagnostic.span_err(item_sp, "rustc_deprecated attribute must be paired with \
either stable or unstable attribute");
@@ -606,12 +612,77 @@ fn find_stability_generic<'a, I>(diagnostic: &SpanHandler,
stab
}
fn find_deprecation_generic<'a, I>(diagnostic: &SpanHandler,
attrs_iter: I,
item_sp: Span)
-> Option<Deprecation>
where I: Iterator<Item = &'a Attribute>
{
let mut depr: Option<Deprecation> = None;
'outer: for attr in attrs_iter {
if attr.name() != "deprecated" {
continue
}
mark_used(attr);
if depr.is_some() {
diagnostic.span_err(item_sp, "multiple deprecated attributes");
break
}
depr = if let Some(metas) = attr.meta_item_list() {
let get = |meta: &MetaItem, item: &mut Option<InternedString>| {
if item.is_some() {
diagnostic.span_err(meta.span, &format!("multiple '{}' items",
meta.name()));
return false
}
if let Some(v) = meta.value_str() {
*item = Some(v);
true
} else {
diagnostic.span_err(meta.span, "incorrect meta item");
false
}
};
let mut since = None;
let mut note = None;
for meta in metas {
match &*meta.name() {
"since" => if !get(meta, &mut since) { continue 'outer },
"note" => if !get(meta, &mut note) { continue 'outer },
_ => {
diagnostic.span_err(meta.span, &format!("unknown meta item '{}'",
meta.name()));
continue 'outer
}
}
}
Some(Deprecation {since: since, note: note})
} else {
Some(Deprecation{since: None, note: None})
}
}
depr
}
/// Find the first stability attribute. `None` if none exists.
pub fn find_stability(diagnostic: &SpanHandler, attrs: &[Attribute],
item_sp: Span) -> Option<Stability> {
find_stability_generic(diagnostic, attrs.iter(), item_sp)
}
/// Find the deprecation attribute. `None` if none exists.
pub fn find_deprecation(diagnostic: &SpanHandler, attrs: &[Attribute],
item_sp: Span) -> Option<Deprecation> {
find_deprecation_generic(diagnostic, attrs.iter(), item_sp)
}
pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[P<MetaItem>]) {
let mut set = HashSet::new();
for meta in metas {

View File

@@ -230,6 +230,9 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status
// Allow attributes on expressions and non-item statements
("stmt_expr_attributes", "1.6.0", Some(15701), Active),
// Allows `#[deprecated]` attribute
("deprecated", "1.6.0", Some(29935), Active),
];
// (changing above list without updating src/doc/reference.md makes @cmr sad)
@@ -377,6 +380,7 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeGat
("must_use", Whitelisted, Ungated),
("stable", Whitelisted, Ungated),
("unstable", Whitelisted, Ungated),
("deprecated", Normal, Gated("deprecated", "`#[deprecated]` attribute is unstable")),
("rustc_paren_sugar", Normal, Gated("unboxed_closures",
"unboxed_closures are still evolving")),
@@ -539,6 +543,7 @@ pub struct Features {
pub braced_empty_structs: bool,
pub staged_api: bool,
pub stmt_expr_attributes: bool,
pub deprecated: bool,
}
impl Features {
@@ -573,6 +578,7 @@ impl Features {
braced_empty_structs: false,
staged_api: false,
stmt_expr_attributes: false,
deprecated: false,
}
}
}
@@ -1151,6 +1157,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
braced_empty_structs: cx.has_feature("braced_empty_structs"),
staged_api: cx.has_feature("staged_api"),
stmt_expr_attributes: cx.has_feature("stmt_expr_attributes"),
deprecated: cx.has_feature("deprecated"),
}
}