@@ -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 ) ]
130129pub 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 ) ]
715684pub 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
0 commit comments