@@ -139,7 +139,7 @@ pub enum StabilityLevel {
139
139
/// `#[stable]`
140
140
Stable {
141
141
/// Rust release which stabilized this feature.
142
- since : Since ,
142
+ since : StableSince ,
143
143
/// Is this item allowed to be referred to on stable, despite being contained in unstable
144
144
/// modules?
145
145
allowed_through_unstable_modules : bool ,
@@ -149,7 +149,7 @@ pub enum StabilityLevel {
149
149
/// Rust release in which a feature is stabilized.
150
150
#[ derive( Encodable , Decodable , PartialEq , Copy , Clone , Debug , Eq , Hash ) ]
151
151
#[ derive( HashStable_Generic ) ]
152
- pub enum Since {
152
+ pub enum StableSince {
153
153
Version ( RustcVersion ) ,
154
154
/// Stabilized in the upcoming version, whatever number that is.
155
155
Current ,
@@ -378,16 +378,16 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
378
378
379
379
let since = if let Some ( since) = since {
380
380
if since. as_str ( ) == VERSION_PLACEHOLDER {
381
- Since :: Current
381
+ StableSince :: Current
382
382
} else if let Some ( version) = parse_version ( since) {
383
- Since :: Version ( version)
383
+ StableSince :: Version ( version)
384
384
} else {
385
385
sess. emit_err ( session_diagnostics:: InvalidSince { span : attr. span } ) ;
386
- Since :: Err
386
+ StableSince :: Err
387
387
}
388
388
} else {
389
389
sess. emit_err ( session_diagnostics:: MissingSince { span : attr. span } ) ;
390
- Since :: Err
390
+ StableSince :: Err
391
391
} ;
392
392
393
393
match feature {
@@ -720,17 +720,49 @@ pub fn eval_condition(
720
720
721
721
#[ derive( Copy , Debug , Encodable , Decodable , Clone , HashStable_Generic ) ]
722
722
pub struct Deprecation {
723
- pub since : Option < Symbol > ,
723
+ pub since : DeprecatedSince ,
724
724
/// The note to issue a reason.
725
725
pub note : Option < Symbol > ,
726
726
/// A text snippet used to completely replace any use of the deprecated item in an expression.
727
727
///
728
728
/// This is currently unstable.
729
729
pub suggestion : Option < Symbol > ,
730
+ }
731
+
732
+ /// Release in which an API is deprecated.
733
+ #[ derive( Copy , Debug , Encodable , Decodable , Clone , HashStable_Generic ) ]
734
+ pub enum DeprecatedSince {
735
+ RustcVersion ( RustcVersion ) ,
736
+ /// Deprecated in the future ("to be determined").
737
+ Future ,
738
+ /// `feature(staged_api)` is off. Deprecation versions outside the standard
739
+ /// library are allowed to be arbitrary strings, for better or worse.
740
+ NonStandard ( Symbol ) ,
741
+ /// Deprecation version is unspecified but optional.
742
+ Unspecified ,
743
+ /// Failed to parse a deprecation version, or the deprecation version is
744
+ /// unspecified and required. An error has already been emitted.
745
+ Err ,
746
+ }
747
+
748
+ impl Deprecation {
749
+ /// Whether an item marked with #[deprecated(since = "X")] is currently
750
+ /// deprecated (i.e., whether X is not greater than the current rustc
751
+ /// version).
752
+ pub fn is_in_effect ( & self ) -> bool {
753
+ match self . since {
754
+ DeprecatedSince :: RustcVersion ( since) => since <= RustcVersion :: CURRENT ,
755
+ DeprecatedSince :: Future => false ,
756
+ // The `since` field doesn't have semantic purpose without `#![staged_api]`.
757
+ DeprecatedSince :: NonStandard ( _) => true ,
758
+ // Assume deprecation is in effect if "since" field is absent or invalid.
759
+ DeprecatedSince :: Unspecified | DeprecatedSince :: Err => true ,
760
+ }
761
+ }
730
762
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 ,
763
+ pub fn is_since_rustc_version ( & self ) -> bool {
764
+ matches ! ( self . since , DeprecatedSince :: RustcVersion ( _ ) )
765
+ }
734
766
}
735
767
736
768
/// Finds the deprecation attribute. `None` if none exists.
@@ -839,22 +871,30 @@ pub fn find_deprecation(
839
871
}
840
872
}
841
873
842
- if is_rustc {
843
- if since. is_none ( ) {
844
- sess. emit_err ( session_diagnostics:: MissingSince { span : attr. span } ) ;
845
- continue ;
874
+ let since = if let Some ( since) = since {
875
+ if since. as_str ( ) == "TBD" {
876
+ DeprecatedSince :: Future
877
+ } else if !is_rustc {
878
+ DeprecatedSince :: NonStandard ( since)
879
+ } else if let Some ( version) = parse_version ( since) {
880
+ DeprecatedSince :: RustcVersion ( version)
881
+ } else {
882
+ sess. emit_err ( session_diagnostics:: InvalidSince { span : attr. span } ) ;
883
+ DeprecatedSince :: Err
846
884
}
885
+ } else if is_rustc {
886
+ sess. emit_err ( session_diagnostics:: MissingSince { span : attr. span } ) ;
887
+ DeprecatedSince :: Err
888
+ } else {
889
+ DeprecatedSince :: Unspecified
890
+ } ;
847
891
848
- if note. is_none ( ) {
849
- sess. emit_err ( session_diagnostics:: MissingNote { span : attr. span } ) ;
850
- continue ;
851
- }
892
+ if is_rustc && note. is_none ( ) {
893
+ sess. emit_err ( session_diagnostics:: MissingNote { span : attr. span } ) ;
894
+ continue ;
852
895
}
853
896
854
- depr = Some ( (
855
- Deprecation { since, note, suggestion, is_since_rustc_version : is_rustc } ,
856
- attr. span ,
857
- ) ) ;
897
+ depr = Some ( ( Deprecation { since, note, suggestion } , attr. span ) ) ;
858
898
}
859
899
860
900
depr
0 commit comments