Parse rustc_deprecated as deprecated attribute

This commit is contained in:
Mark Rousskov 2020-07-20 10:11:53 -04:00
parent 05630b06fd
commit c5cc29b0e0
4 changed files with 58 additions and 48 deletions

View file

@ -124,7 +124,6 @@ pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Op
///
/// - `#[stable]`
/// - `#[unstable]`
/// - `#[rustc_deprecated]`
#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(HashStable_Generic)]
pub struct Stability {
@ -213,7 +212,6 @@ where
'outer: for attr in attrs_iter {
if ![
sym::rustc_deprecated,
sym::rustc_const_unstable,
sym::rustc_const_stable,
sym::unstable,
@ -299,35 +297,6 @@ where
let meta_name = meta.name_or_empty();
match meta_name {
sym::rustc_deprecated => {
if rustc_depr.is_some() {
struct_span_err!(
diagnostic,
item_sp,
E0540,
"multiple rustc_deprecated attributes"
)
.emit();
continue 'outer;
}
get_meta!(since, reason, suggestion);
match (since, reason) {
(Some(since), Some(reason)) => {
rustc_depr = Some(RustcDeprecation { since, reason, suggestion })
}
(None, _) => {
handle_errors(sess, attr.span, AttrError::MissingSince);
continue;
}
_ => {
struct_span_err!(diagnostic, attr.span, E0543, "missing 'reason'")
.emit();
continue;
}
}
}
sym::rustc_const_unstable | sym::unstable => {
if meta_name == sym::unstable && stab.is_some() {
handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels);
@ -714,7 +683,16 @@ pub fn eval_condition(
#[derive(RustcEncodable, RustcDecodable, Clone, HashStable_Generic)]
pub struct Deprecation {
pub since: Option<Symbol>,
/// The note to issue a reason.
pub note: Option<Symbol>,
/// A text snippet used to completely replace any use of the deprecated item in an expression.
///
/// This is currently unstable.
pub suggestion: Option<Symbol>,
/// Whether to treat the since attribute as being a Rust version identifier
/// (rather than an opaque string).
pub is_since_rustc_version: bool,
}
/// Finds the deprecation attribute. `None` if none exists.
@ -738,7 +716,7 @@ where
let diagnostic = &sess.span_diagnostic;
'outer: for attr in attrs_iter {
if !attr.check_name(sym::deprecated) {
if !(attr.check_name(sym::deprecated) || attr.check_name(sym::rustc_deprecated)) {
continue;
}
@ -751,11 +729,12 @@ where
Some(meta) => meta,
None => continue,
};
depr = match &meta.kind {
MetaItemKind::Word => Some(Deprecation { since: None, note: None }),
MetaItemKind::NameValue(..) => {
meta.value_str().map(|note| Deprecation { since: None, note: Some(note) })
}
let mut since = None;
let mut note = None;
let mut suggestion = None;
match &meta.kind {
MetaItemKind::Word => {}
MetaItemKind::NameValue(..) => note = meta.value_str(),
MetaItemKind::List(list) => {
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
if item.is_some() {
@ -789,8 +768,6 @@ where
}
};
let mut since = None;
let mut note = None;
for meta in list {
match meta {
NestedMetaItem::MetaItem(mi) => match mi.name_or_empty() {
@ -799,18 +776,32 @@ where
continue 'outer;
}
}
sym::note => {
sym::note if attr.check_name(sym::deprecated) => {
if !get(mi, &mut note) {
continue 'outer;
}
}
sym::reason if attr.check_name(sym::rustc_deprecated) => {
if !get(mi, &mut note) {
continue 'outer;
}
}
sym::suggestion if attr.check_name(sym::rustc_deprecated) => {
if !get(mi, &mut suggestion) {
continue 'outer;
}
}
_ => {
handle_errors(
sess,
meta.span(),
AttrError::UnknownMetaItem(
pprust::path_to_string(&mi.path),
&["since", "note"],
if attr.check_name(sym::deprecated) {
&["since", "note"]
} else {
&["since", "reason", "suggestion"]
},
),
);
continue 'outer;
@ -829,10 +820,29 @@ where
}
}
}
Some(Deprecation { since, note })
}
};
}
if suggestion.is_some() && attr.check_name(sym::deprecated) {
unreachable!("only allowed on rustc_deprecated")
}
if attr.check_name(sym::rustc_deprecated) {
if since.is_none() {
handle_errors(sess, attr.span, AttrError::MissingSince);
continue;
}
if note.is_none() {
struct_span_err!(diagnostic, attr.span, E0543, "missing 'reason'").emit();
continue;
}
}
mark_used(&attr);
let is_since_rustc_version = attr.check_name(sym::rustc_deprecated);
depr = Some(Deprecation { since, note, suggestion, is_since_rustc_version });
}
depr

View file

@ -588,7 +588,7 @@ E0770: include_str!("./error_codes/E0770.md"),
E0521, // borrowed data escapes outside of closure
E0523,
// E0526, // shuffle indices are not constant
E0540, // multiple rustc_deprecated attributes
// E0540, // multiple rustc_deprecated attributes
E0542, // missing 'since'
E0543, // missing 'reason'
E0544, // multiple stability levels

View file

@ -62,7 +62,7 @@ fn multiple3() { }
#[rustc_deprecated(since = "b", reason = "text")]
#[rustc_const_unstable(feature = "c", issue = "none")]
#[rustc_const_unstable(feature = "d", issue = "none")] //~ ERROR multiple stability levels
pub const fn multiple4() { } //~ ERROR multiple rustc_deprecated attributes [E0540]
pub const fn multiple4() { } //~ ERROR multiple deprecated attributes
//~^ ERROR Invalid stability or deprecation version found
#[rustc_deprecated(since = "a", reason = "text")]

View file

@ -82,7 +82,7 @@ error[E0544]: multiple stability levels
LL | #[stable(feature = "a", since = "b")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0540]: multiple rustc_deprecated attributes
error[E0550]: multiple deprecated attributes
--> $DIR/stability-attribute-sanity.rs:65:1
|
LL | pub const fn multiple4() { }
@ -108,5 +108,5 @@ LL | fn deprecated_without_unstable_or_stable() { }
error: aborting due to 18 previous errors
Some errors have detailed explanations: E0539, E0541.
Some errors have detailed explanations: E0539, E0541, E0550.
For more information about an error, try `rustc --explain E0539`.