Skip to content

Commit c5cc29b

Browse files
Parse rustc_deprecated as deprecated attribute
1 parent 05630b0 commit c5cc29b

File tree

4 files changed

+57
-47
lines changed

4 files changed

+57
-47
lines changed

src/librustc_attr/builtin.rs

Lines changed: 53 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ pub fn find_unwind_attr(diagnostic: Option<&Handler>, attrs: &[Attribute]) -> Op
124124
///
125125
/// - `#[stable]`
126126
/// - `#[unstable]`
127-
/// - `#[rustc_deprecated]`
128127
#[derive(RustcEncodable, RustcDecodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
129128
#[derive(HashStable_Generic)]
130129
pub struct Stability {
@@ -213,7 +212,6 @@ where
213212

214213
'outer: for attr in attrs_iter {
215214
if ![
216-
sym::rustc_deprecated,
217215
sym::rustc_const_unstable,
218216
sym::rustc_const_stable,
219217
sym::unstable,
@@ -299,35 +297,6 @@ where
299297

300298
let meta_name = meta.name_or_empty();
301299
match meta_name {
302-
sym::rustc_deprecated => {
303-
if rustc_depr.is_some() {
304-
struct_span_err!(
305-
diagnostic,
306-
item_sp,
307-
E0540,
308-
"multiple rustc_deprecated attributes"
309-
)
310-
.emit();
311-
continue 'outer;
312-
}
313-
314-
get_meta!(since, reason, suggestion);
315-
316-
match (since, reason) {
317-
(Some(since), Some(reason)) => {
318-
rustc_depr = Some(RustcDeprecation { since, reason, suggestion })
319-
}
320-
(None, _) => {
321-
handle_errors(sess, attr.span, AttrError::MissingSince);
322-
continue;
323-
}
324-
_ => {
325-
struct_span_err!(diagnostic, attr.span, E0543, "missing 'reason'")
326-
.emit();
327-
continue;
328-
}
329-
}
330-
}
331300
sym::rustc_const_unstable | sym::unstable => {
332301
if meta_name == sym::unstable && stab.is_some() {
333302
handle_errors(sess, attr.span, AttrError::MultipleStabilityLevels);
@@ -714,7 +683,16 @@ pub fn eval_condition(
714683
#[derive(RustcEncodable, RustcDecodable, Clone, HashStable_Generic)]
715684
pub struct Deprecation {
716685
pub since: Option<Symbol>,
686+
/// The note to issue a reason.
717687
pub note: Option<Symbol>,
688+
/// A text snippet used to completely replace any use of the deprecated item in an expression.
689+
///
690+
/// This is currently unstable.
691+
pub suggestion: Option<Symbol>,
692+
693+
/// Whether to treat the since attribute as being a Rust version identifier
694+
/// (rather than an opaque string).
695+
pub is_since_rustc_version: bool,
718696
}
719697

720698
/// Finds the deprecation attribute. `None` if none exists.
@@ -738,7 +716,7 @@ where
738716
let diagnostic = &sess.span_diagnostic;
739717

740718
'outer: for attr in attrs_iter {
741-
if !attr.check_name(sym::deprecated) {
719+
if !(attr.check_name(sym::deprecated) || attr.check_name(sym::rustc_deprecated)) {
742720
continue;
743721
}
744722

@@ -751,11 +729,12 @@ where
751729
Some(meta) => meta,
752730
None => continue,
753731
};
754-
depr = match &meta.kind {
755-
MetaItemKind::Word => Some(Deprecation { since: None, note: None }),
756-
MetaItemKind::NameValue(..) => {
757-
meta.value_str().map(|note| Deprecation { since: None, note: Some(note) })
758-
}
732+
let mut since = None;
733+
let mut note = None;
734+
let mut suggestion = None;
735+
match &meta.kind {
736+
MetaItemKind::Word => {}
737+
MetaItemKind::NameValue(..) => note = meta.value_str(),
759738
MetaItemKind::List(list) => {
760739
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
761740
if item.is_some() {
@@ -789,8 +768,6 @@ where
789768
}
790769
};
791770

792-
let mut since = None;
793-
let mut note = None;
794771
for meta in list {
795772
match meta {
796773
NestedMetaItem::MetaItem(mi) => match mi.name_or_empty() {
@@ -799,18 +776,32 @@ where
799776
continue 'outer;
800777
}
801778
}
802-
sym::note => {
779+
sym::note if attr.check_name(sym::deprecated) => {
780+
if !get(mi, &mut note) {
781+
continue 'outer;
782+
}
783+
}
784+
sym::reason if attr.check_name(sym::rustc_deprecated) => {
803785
if !get(mi, &mut note) {
804786
continue 'outer;
805787
}
806788
}
789+
sym::suggestion if attr.check_name(sym::rustc_deprecated) => {
790+
if !get(mi, &mut suggestion) {
791+
continue 'outer;
792+
}
793+
}
807794
_ => {
808795
handle_errors(
809796
sess,
810797
meta.span(),
811798
AttrError::UnknownMetaItem(
812799
pprust::path_to_string(&mi.path),
813-
&["since", "note"],
800+
if attr.check_name(sym::deprecated) {
801+
&["since", "note"]
802+
} else {
803+
&["since", "reason", "suggestion"]
804+
},
814805
),
815806
);
816807
continue 'outer;
@@ -829,10 +820,29 @@ where
829820
}
830821
}
831822
}
823+
}
824+
}
825+
826+
if suggestion.is_some() && attr.check_name(sym::deprecated) {
827+
unreachable!("only allowed on rustc_deprecated")
828+
}
832829

833-
Some(Deprecation { since, note })
830+
if attr.check_name(sym::rustc_deprecated) {
831+
if since.is_none() {
832+
handle_errors(sess, attr.span, AttrError::MissingSince);
833+
continue;
834834
}
835-
};
835+
836+
if note.is_none() {
837+
struct_span_err!(diagnostic, attr.span, E0543, "missing 'reason'").emit();
838+
continue;
839+
}
840+
}
841+
842+
mark_used(&attr);
843+
844+
let is_since_rustc_version = attr.check_name(sym::rustc_deprecated);
845+
depr = Some(Deprecation { since, note, suggestion, is_since_rustc_version });
836846
}
837847

838848
depr

src/librustc_error_codes/error_codes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ E0770: include_str!("./error_codes/E0770.md"),
588588
E0521, // borrowed data escapes outside of closure
589589
E0523,
590590
// E0526, // shuffle indices are not constant
591-
E0540, // multiple rustc_deprecated attributes
591+
// E0540, // multiple rustc_deprecated attributes
592592
E0542, // missing 'since'
593593
E0543, // missing 'reason'
594594
E0544, // multiple stability levels

src/test/ui/stability-attribute/stability-attribute-sanity.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ fn multiple3() { }
6262
#[rustc_deprecated(since = "b", reason = "text")]
6363
#[rustc_const_unstable(feature = "c", issue = "none")]
6464
#[rustc_const_unstable(feature = "d", issue = "none")] //~ ERROR multiple stability levels
65-
pub const fn multiple4() { } //~ ERROR multiple rustc_deprecated attributes [E0540]
65+
pub const fn multiple4() { } //~ ERROR multiple deprecated attributes
6666
//~^ ERROR Invalid stability or deprecation version found
6767

6868
#[rustc_deprecated(since = "a", reason = "text")]

src/test/ui/stability-attribute/stability-attribute-sanity.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ error[E0544]: multiple stability levels
8282
LL | #[stable(feature = "a", since = "b")]
8383
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8484

85-
error[E0540]: multiple rustc_deprecated attributes
85+
error[E0550]: multiple deprecated attributes
8686
--> $DIR/stability-attribute-sanity.rs:65:1
8787
|
8888
LL | pub const fn multiple4() { }
@@ -108,5 +108,5 @@ LL | fn deprecated_without_unstable_or_stable() { }
108108

109109
error: aborting due to 18 previous errors
110110

111-
Some errors have detailed explanations: E0539, E0541.
111+
Some errors have detailed explanations: E0539, E0541, E0550.
112112
For more information about an error, try `rustc --explain E0539`.

0 commit comments

Comments
 (0)