@@ -13,6 +13,7 @@ use rustc_session::parse::{feature_err, ParseSess};
13
13
use rustc_session:: 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 } ;
@@ -23,10 +24,7 @@ use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause};
23
24
/// For more, see [this pull request](https://github.com/rust-lang/rust/pull/100591).
24
25
pub const VERSION_PLACEHOLDER : & str = "CURRENT_RUSTC_VERSION" ;
25
26
26
- pub fn rust_version_symbol ( ) -> Symbol {
27
- let version = option_env ! ( "CFG_RELEASE" ) . unwrap_or ( "<current>" ) ;
28
- Symbol :: intern ( & version)
29
- }
27
+ pub const CURRENT_RUSTC_VERSION : & str = env ! ( "CFG_RELEASE" ) ;
30
28
31
29
pub fn is_builtin_attr ( attr : & Attribute ) -> bool {
32
30
attr. is_doc_comment ( ) || attr. ident ( ) . is_some_and ( |ident| is_builtin_attr_name ( ident. name ) )
@@ -144,13 +142,24 @@ pub enum StabilityLevel {
144
142
/// `#[stable]`
145
143
Stable {
146
144
/// Rust release which stabilized this feature.
147
- since : Symbol ,
145
+ since : Since ,
148
146
/// Is this item allowed to be referred to on stable, despite being contained in unstable
149
147
/// modules?
150
148
allowed_through_unstable_modules : bool ,
151
149
} ,
152
150
}
153
151
152
+ /// Rust release in which a feature is stabilized.
153
+ #[ derive( Encodable , Decodable , PartialEq , Copy , Clone , Debug , Eq , Hash ) ]
154
+ #[ derive( HashStable_Generic ) ]
155
+ pub enum Since {
156
+ Version ( Version ) ,
157
+ /// Stabilized in the upcoming version, whatever number that is.
158
+ Current ,
159
+ /// Failed to parse a stabilization version.
160
+ Err ,
161
+ }
162
+
154
163
impl StabilityLevel {
155
164
pub fn is_unstable ( & self ) -> bool {
156
165
matches ! ( self , StabilityLevel :: Unstable { .. } )
@@ -372,22 +381,24 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
372
381
373
382
let since = if let Some ( since) = since {
374
383
if since. as_str ( ) == VERSION_PLACEHOLDER {
375
- Ok ( rust_version_symbol ( ) )
376
- } else if parse_version ( since. as_str ( ) , false ) . is_some ( ) {
377
- Ok ( since )
384
+ Since :: Current
385
+ } else if let Some ( version ) = parse_version ( since. as_str ( ) , false ) {
386
+ Since :: Version ( version )
378
387
} else {
379
- Err ( sess. emit_err ( session_diagnostics:: InvalidSince { span : attr. span } ) )
388
+ sess. emit_err ( session_diagnostics:: InvalidSince { span : attr. span } ) ;
389
+ Since :: Err
380
390
}
381
391
} else {
382
- Err ( sess. emit_err ( session_diagnostics:: MissingSince { span : attr. span } ) )
392
+ sess. emit_err ( session_diagnostics:: MissingSince { span : attr. span } ) ;
393
+ Since :: Err
383
394
} ;
384
395
385
- match ( feature, since ) {
386
- ( Ok ( feature) , Ok ( since ) ) => {
396
+ match feature {
397
+ Ok ( feature) => {
387
398
let level = StabilityLevel :: Stable { since, allowed_through_unstable_modules : false } ;
388
399
Some ( ( feature, level) )
389
400
}
390
- ( Err ( ErrorGuaranteed { .. } ) , _ ) | ( _ , Err ( ErrorGuaranteed { .. } ) ) => None ,
401
+ Err ( ErrorGuaranteed { .. } ) => None ,
391
402
}
392
403
}
393
404
@@ -556,11 +567,12 @@ fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &ParseSess, features: &F
556
567
}
557
568
}
558
569
559
- #[ derive( Clone , Debug , PartialEq , Eq , PartialOrd , Ord ) ]
560
- struct Version {
561
- major : u16 ,
562
- minor : u16 ,
563
- patch : u16 ,
570
+ #[ derive( Encodable , Decodable , Copy , Clone , Debug , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
571
+ #[ derive( HashStable_Generic ) ]
572
+ pub struct Version {
573
+ pub major : u16 ,
574
+ pub minor : u16 ,
575
+ pub patch : u16 ,
564
576
}
565
577
566
578
fn parse_version ( s : & str , allow_appendix : bool ) -> Option < Version > {
@@ -576,6 +588,12 @@ fn parse_version(s: &str, allow_appendix: bool) -> Option<Version> {
576
588
Some ( Version { major, minor, patch } )
577
589
}
578
590
591
+ impl Display for Version {
592
+ fn fmt ( & self , formatter : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
593
+ write ! ( formatter, "{}.{}.{}" , self . major, self . minor, self . patch)
594
+ }
595
+ }
596
+
579
597
/// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to
580
598
/// evaluate individual items.
581
599
pub fn eval_condition (
@@ -609,7 +627,7 @@ pub fn eval_condition(
609
627
sess. emit_warning ( session_diagnostics:: UnknownVersionLiteral { span : * span } ) ;
610
628
return false ;
611
629
} ;
612
- let rustc_version = parse_version ( env ! ( "CFG_RELEASE" ) , true ) . unwrap ( ) ;
630
+ let rustc_version = parse_version ( CURRENT_RUSTC_VERSION , true ) . unwrap ( ) ;
613
631
614
632
// See https://github.com/rust-lang/rust/issues/64796#issuecomment-640851454 for details
615
633
if sess. assume_incomplete_release {
0 commit comments