@@ -70,7 +70,6 @@ pub enum OptimizeAttr {
7070#[ derive( HashStable_Generic ) ]
7171pub struct Stability {
7272 pub level : StabilityLevel ,
73- pub feature : Symbol ,
7473}
7574
7675impl Stability {
@@ -91,10 +90,7 @@ impl Stability {
9190#[ derive( Encodable , Decodable , Copy , Clone , Debug , PartialEq , Eq , Hash ) ]
9291#[ derive( HashStable_Generic ) ]
9392pub struct ConstStability {
94- pub level : StabilityLevel ,
95- /// This can be `None` for functions that do not have an explicit const feature.
96- /// We still track them for recursive const stability checks.
97- pub feature : Option < Symbol > ,
93+ pub level : ConstStabilityLevel ,
9894 /// This is true iff the `const_stable_indirect` attribute is present.
9995 pub const_stable_indirect : bool ,
10096 /// whether the function has a `#[rustc_promotable]` attribute
@@ -103,11 +99,15 @@ pub struct ConstStability {
10399
104100impl ConstStability {
105101 pub fn is_const_unstable ( & self ) -> bool {
106- self . level . is_unstable ( )
102+ matches ! ( self . level, ConstStabilityLevel :: Unstable { .. } )
107103 }
108104
109105 pub fn is_const_stable ( & self ) -> bool {
110- self . level . is_stable ( )
106+ matches ! ( self . level, ConstStabilityLevel :: Stable { .. } )
107+ }
108+
109+ pub fn is_implicit ( & self ) -> bool {
110+ matches ! ( self . level, ConstStabilityLevel :: Implicit )
111111 }
112112}
113113
@@ -116,7 +116,6 @@ impl ConstStability {
116116#[ derive( HashStable_Generic ) ]
117117pub struct DefaultBodyStability {
118118 pub level : StabilityLevel ,
119- pub feature : Symbol ,
120119}
121120
122121/// The available stability levels.
@@ -125,31 +124,9 @@ pub struct DefaultBodyStability {
125124pub enum StabilityLevel {
126125 /// `#[unstable]`
127126 Unstable {
128- /// Reason for the current stability level.
129- reason : UnstableReason ,
130- /// Relevant `rust-lang/rust` issue.
131- issue : Option < NonZero < u32 > > ,
127+ /// The information unique to each `#[unstable]` attribute
128+ unstables : Unstability ,
132129 is_soft : bool ,
133- /// If part of a feature is stabilized and a new feature is added for the remaining parts,
134- /// then the `implied_by` attribute is used to indicate which now-stable feature previously
135- /// contained an item.
136- ///
137- /// ```pseudo-Rust
138- /// #[unstable(feature = "foo", issue = "...")]
139- /// fn foo() {}
140- /// #[unstable(feature = "foo", issue = "...")]
141- /// fn foobar() {}
142- /// ```
143- ///
144- /// ...becomes...
145- ///
146- /// ```pseudo-Rust
147- /// #[stable(feature = "foo", since = "1.XX.X")]
148- /// fn foo() {}
149- /// #[unstable(feature = "foobar", issue = "...", implied_by = "foo")]
150- /// fn foobar() {}
151- /// ```
152- implied_by : Option < Symbol > ,
153130 } ,
154131 /// `#[stable]`
155132 Stable {
@@ -161,6 +138,20 @@ pub enum StabilityLevel {
161138 } ,
162139}
163140
141+ /// The available const-stability levels for const functions.
142+ /// For details see [#131349](https://github.com/rust-lang/rust/pull/131349).
143+ #[ derive( Encodable , Decodable , PartialEq , Copy , Clone , Debug , Eq , Hash ) ]
144+ #[ derive( HashStable_Generic ) ]
145+ pub enum ConstStabilityLevel {
146+ /// For functions declared const-stable
147+ Stable { since : StableSince } ,
148+ /// For functions declared const-unstable
149+ Unstable { unstables : Unstability } ,
150+ /// For functions with no explicit const-stability attribute that require checking recursive
151+ /// const stability. This is either an unmarked const fn or a `const_stable_indirect` intrinsic.
152+ Implicit ,
153+ }
154+
164155/// Rust release in which a feature is stabilized.
165156#[ derive( Encodable , Decodable , PartialEq , Copy , Clone , Debug , Eq , PartialOrd , Ord , Hash ) ]
166157#[ derive( HashStable_Generic ) ]
@@ -187,6 +178,37 @@ impl StabilityLevel {
187178 }
188179}
189180
181+ /// An instance of an `#[unstable]`, `#[rustc_const_unstable]`, or similar attribute
182+ #[ derive( Encodable , Decodable , PartialEq , Copy , Clone , Debug , Eq , Hash ) ]
183+ #[ derive( HashStable_Generic ) ]
184+ pub struct Unstability {
185+ pub feature : Symbol ,
186+ /// Reason for the current stability level.
187+ pub reason : UnstableReason ,
188+ /// Relevant `rust-lang/rust` issue.
189+ pub issue : Option < NonZero < u32 > > ,
190+ /// If part of a feature is stabilized and a new feature is added for the remaining parts,
191+ /// then the `implied_by` attribute is used to indicate which now-stable feature previously
192+ /// contained an item.
193+ ///
194+ /// ```pseudo-Rust
195+ /// #[unstable(feature = "foo", issue = "...")]
196+ /// fn foo() {}
197+ /// #[unstable(feature = "foo", issue = "...")]
198+ /// fn foobar() {}
199+ /// ```
200+ ///
201+ /// ...becomes...
202+ ///
203+ /// ```pseudo-Rust
204+ /// #[stable(feature = "foo", since = "1.XX.X")]
205+ /// fn foo() {}
206+ /// #[unstable(feature = "foobar", issue = "...", implied_by = "foo")]
207+ /// fn foobar() {}
208+ /// ```
209+ pub implied_by : Option < Symbol > ,
210+ }
211+
190212#[ derive( Encodable , Decodable , PartialEq , Copy , Clone , Debug , Eq , Hash ) ]
191213#[ derive( HashStable_Generic ) ]
192214pub enum UnstableReason {
@@ -233,8 +255,8 @@ pub fn find_stability(
233255 break ;
234256 }
235257
236- if let Some ( ( feature , level) ) = parse_unstability ( sess, attr) {
237- stab = Some ( ( Stability { level, feature } , attr. span ) ) ;
258+ if let Some ( level) = parse_unstability ( sess, attr) {
259+ stab = Some ( ( Stability { level } , attr. span ) ) ;
238260 }
239261 }
240262 sym:: stable => {
@@ -243,8 +265,8 @@ pub fn find_stability(
243265 . emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ;
244266 break ;
245267 }
246- if let Some ( ( feature , level) ) = parse_stability ( sess, attr) {
247- stab = Some ( ( Stability { level, feature } , attr. span ) ) ;
268+ if let Some ( level) = parse_stability ( sess, attr) {
269+ stab = Some ( ( Stability { level } , attr. span ) ) ;
248270 }
249271 }
250272 _ => { }
@@ -284,6 +306,10 @@ pub fn find_const_stability(
284306 let mut const_stab: Option < ( ConstStability , Span ) > = None ;
285307 let mut promotable = false ;
286308 let mut const_stable_indirect = None ;
309+ let const_stability_level = |level| match level {
310+ StabilityLevel :: Unstable { unstables, .. } => ConstStabilityLevel :: Unstable { unstables } ,
311+ StabilityLevel :: Stable { since, .. } => ConstStabilityLevel :: Stable { since } ,
312+ } ;
287313
288314 for attr in attrs {
289315 match attr. name_or_empty ( ) {
@@ -296,11 +322,10 @@ pub fn find_const_stability(
296322 break ;
297323 }
298324
299- if let Some ( ( feature , level) ) = parse_unstability ( sess, attr) {
325+ if let Some ( level) = parse_unstability ( sess, attr) {
300326 const_stab = Some ( (
301327 ConstStability {
302- level,
303- feature : Some ( feature) ,
328+ level : const_stability_level ( level) ,
304329 const_stable_indirect : false ,
305330 promotable : false ,
306331 } ,
@@ -314,11 +339,10 @@ pub fn find_const_stability(
314339 . emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ;
315340 break ;
316341 }
317- if let Some ( ( feature , level) ) = parse_stability ( sess, attr) {
342+ if let Some ( level) = parse_stability ( sess, attr) {
318343 const_stab = Some ( (
319344 ConstStability {
320- level,
321- feature : Some ( feature) ,
345+ level : const_stability_level ( level) ,
322346 const_stable_indirect : false ,
323347 promotable : false ,
324348 } ,
@@ -369,15 +393,9 @@ pub fn find_const_stability(
369393 // staged_api crate.
370394 if ( is_const_fn || const_stable_indirect. is_some ( ) ) && const_stab. is_none ( ) {
371395 let c = ConstStability {
372- feature : None ,
396+ level : ConstStabilityLevel :: Implicit ,
373397 const_stable_indirect : const_stable_indirect. is_some ( ) ,
374398 promotable : false ,
375- level : StabilityLevel :: Unstable {
376- reason : UnstableReason :: Default ,
377- issue : None ,
378- is_soft : false ,
379- implied_by : None ,
380- } ,
381399 } ;
382400 const_stab = Some ( ( c, const_stable_indirect. unwrap_or ( DUMMY_SP ) ) ) ;
383401 }
@@ -401,8 +419,8 @@ pub fn find_body_stability(
401419 break ;
402420 }
403421
404- if let Some ( ( feature , level) ) = parse_unstability ( sess, attr) {
405- body_stab = Some ( ( DefaultBodyStability { level, feature } , attr. span ) ) ;
422+ if let Some ( level) = parse_unstability ( sess, attr) {
423+ body_stab = Some ( ( DefaultBodyStability { level } , attr. span ) ) ;
406424 }
407425 }
408426 }
@@ -428,7 +446,7 @@ fn insert_or_error(sess: &Session, meta: &MetaItem, item: &mut Option<Symbol>) -
428446
429447/// Read the content of a `stable`/`rustc_const_stable` attribute, and return the feature name and
430448/// its stability information.
431- fn parse_stability ( sess : & Session , attr : & Attribute ) -> Option < ( Symbol , StabilityLevel ) > {
449+ fn parse_stability ( sess : & Session , attr : & Attribute ) -> Option < StabilityLevel > {
432450 let meta = attr. meta ( ) ?;
433451 let MetaItem { kind : MetaItemKind :: List ( ref metas) , .. } = meta else { return None } ;
434452
@@ -482,17 +500,16 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
482500 } ;
483501
484502 match feature {
485- Ok ( feature) => {
486- let level = StabilityLevel :: Stable { since, allowed_through_unstable_modules : false } ;
487- Some ( ( feature, level) )
503+ Ok ( _feature) => {
504+ Some ( StabilityLevel :: Stable { since, allowed_through_unstable_modules : false } )
488505 }
489506 Err ( ErrorGuaranteed { .. } ) => None ,
490507 }
491508}
492509
493510/// Read the content of a `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable`
494511/// attribute, and return the feature name and its stability information.
495- fn parse_unstability ( sess : & Session , attr : & Attribute ) -> Option < ( Symbol , StabilityLevel ) > {
512+ fn parse_unstability ( sess : & Session , attr : & Attribute ) -> Option < StabilityLevel > {
496513 let meta = attr. meta ( ) ?;
497514 let MetaItem { kind : MetaItemKind :: List ( ref metas) , .. } = meta else { return None } ;
498515
@@ -572,12 +589,15 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
572589 match ( feature, issue) {
573590 ( Ok ( feature) , Ok ( _) ) => {
574591 let level = StabilityLevel :: Unstable {
575- reason : UnstableReason :: from_opt_reason ( reason) ,
576- issue : issue_num,
592+ unstables : Unstability {
593+ feature,
594+ reason : UnstableReason :: from_opt_reason ( reason) ,
595+ issue : issue_num,
596+ implied_by,
597+ } ,
577598 is_soft,
578- implied_by,
579599 } ;
580- Some ( ( feature , level) )
600+ Some ( level)
581601 }
582602 ( Err ( ErrorGuaranteed { .. } ) , _) | ( _, Err ( ErrorGuaranteed { .. } ) ) => None ,
583603 }
0 commit comments