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:
@@ -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 {
|
||||
|
||||
@@ -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"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user