@@ -13,6 +13,7 @@ use rustc_session::parse::{feature_err, ParseSess};
13
13
use rustc_session:: { RustcVersion , Session } ;
14
14
use rustc_span:: hygiene:: Transparency ;
15
15
use rustc_span:: { symbol:: sym, symbol:: Symbol , Span } ;
16
+ use std:: fmt:: { self , Display } ;
16
17
use std:: num:: NonZeroU32 ;
17
18
18
19
use crate :: session_diagnostics:: { self , IncorrectReprFormatGenericCause } ;
@@ -720,17 +721,37 @@ pub fn eval_condition(
720
721
721
722
#[ derive( Copy , Debug , Encodable , Decodable , Clone , HashStable_Generic ) ]
722
723
pub struct Deprecation {
723
- pub since : Option < Symbol > ,
724
+ pub since : Option < DeprecatedSince > ,
724
725
/// The note to issue a reason.
725
726
pub note : Option < Symbol > ,
726
727
/// A text snippet used to completely replace any use of the deprecated item in an expression.
727
728
///
728
729
/// This is currently unstable.
729
730
pub suggestion : Option < Symbol > ,
731
+ }
732
+
733
+ /// Release in which an API is deprecated.
734
+ #[ derive( Copy , Debug , Encodable , Decodable , Clone , HashStable_Generic ) ]
735
+ pub enum DeprecatedSince {
736
+ RustcVersion ( RustcVersion ) ,
737
+ /// Deprecated in the future ("to be determined").
738
+ Future ,
739
+ /// `feature(staged_api)` is off, or it's on but the deprecation version
740
+ /// cannot be parsed as a RustcVersion. In the latter case, an error has
741
+ /// already been emitted. In the former case, deprecation versions outside
742
+ /// the standard library are allowed to be arbitrary strings, for better or
743
+ /// worse.
744
+ Symbol ( Symbol ) ,
745
+ }
730
746
731
- /// Whether to treat the since attribute as being a Rust version identifier
732
- /// (rather than an opaque string).
733
- pub is_since_rustc_version : bool ,
747
+ impl Display for DeprecatedSince {
748
+ fn fmt ( & self , formatter : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
749
+ match self {
750
+ DeprecatedSince :: RustcVersion ( since) => Display :: fmt ( since, formatter) ,
751
+ DeprecatedSince :: Future => formatter. write_str ( "TBD" ) ,
752
+ DeprecatedSince :: Symbol ( since) => Display :: fmt ( since, formatter) ,
753
+ }
754
+ }
734
755
}
735
756
736
757
/// Finds the deprecation attribute. `None` if none exists.
@@ -839,22 +860,30 @@ pub fn find_deprecation(
839
860
}
840
861
}
841
862
842
- if is_rustc {
843
- if since. is_none ( ) {
844
- sess. emit_err ( session_diagnostics:: MissingSince { span : attr. span } ) ;
845
- continue ;
863
+ let since = if let Some ( since) = since {
864
+ if since. as_str ( ) == "TBD" {
865
+ Some ( DeprecatedSince :: Future )
866
+ } else if !is_rustc {
867
+ Some ( DeprecatedSince :: Symbol ( since) )
868
+ } else if let Some ( version) = parse_version ( since) {
869
+ Some ( DeprecatedSince :: RustcVersion ( version) )
870
+ } else {
871
+ sess. emit_err ( session_diagnostics:: InvalidSince { span : attr. span } ) ;
872
+ Some ( DeprecatedSince :: Symbol ( since) )
846
873
}
874
+ } else if is_rustc {
875
+ sess. emit_err ( session_diagnostics:: MissingSince { span : attr. span } ) ;
876
+ continue ;
877
+ } else {
878
+ None
879
+ } ;
847
880
848
- if note. is_none ( ) {
849
- sess. emit_err ( session_diagnostics:: MissingNote { span : attr. span } ) ;
850
- continue ;
851
- }
881
+ if is_rustc && note. is_none ( ) {
882
+ sess. emit_err ( session_diagnostics:: MissingNote { span : attr. span } ) ;
883
+ continue ;
852
884
}
853
885
854
- depr = Some ( (
855
- Deprecation { since, note, suggestion, is_since_rustc_version : is_rustc } ,
856
- attr. span ,
857
- ) ) ;
886
+ depr = Some ( ( Deprecation { since, note, suggestion } , attr. span ) ) ;
858
887
}
859
888
860
889
depr
0 commit comments