@@ -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 {
@@ -88,13 +87,11 @@ impl Stability {
8887}
8988
9089/// Represents the `#[rustc_const_unstable]` and `#[rustc_const_stable]` attributes.
90+ /// For details see [the dev guide](https://rustc-dev-guide.rust-lang.org/stability.html#rustc_const_unstable).
9191#[ derive( Encodable , Decodable , Copy , Clone , Debug , PartialEq , Eq , Hash ) ]
9292#[ derive( HashStable_Generic ) ]
9393pub 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 > ,
94+ pub level : ConstStabilityLevel ,
9895 /// This is true iff the `const_stable_indirect` attribute is present.
9996 pub const_stable_indirect : bool ,
10097 /// whether the function has a `#[rustc_promotable]` attribute
@@ -103,11 +100,15 @@ pub struct ConstStability {
103100
104101impl ConstStability {
105102 pub fn is_const_unstable ( & self ) -> bool {
106- self . level . is_unstable ( )
103+ self . level . is_const_unstable ( )
107104 }
108105
109106 pub fn is_const_stable ( & self ) -> bool {
110- self . level . is_stable ( )
107+ self . level . is_const_stable ( )
108+ }
109+
110+ pub fn is_implicit_unstable ( & self ) -> bool {
111+ self . level . is_implicit_unstable ( )
111112 }
112113}
113114
@@ -116,7 +117,6 @@ impl ConstStability {
116117#[ derive( HashStable_Generic ) ]
117118pub struct DefaultBodyStability {
118119 pub level : StabilityLevel ,
119- pub feature : Symbol ,
120120}
121121
122122/// The available stability levels.
@@ -125,31 +125,9 @@ pub struct DefaultBodyStability {
125125pub enum StabilityLevel {
126126 /// `#[unstable]`
127127 Unstable {
128- /// Reason for the current stability level.
129- reason : UnstableReason ,
130- /// Relevant `rust-lang/rust` issue.
131- issue : Option < NonZero < u32 > > ,
128+ /// The information unique to each `#[unstable]` attribute
129+ unstables : Unstability ,
132130 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 > ,
153131 } ,
154132 /// `#[stable]`
155133 Stable {
@@ -161,6 +139,19 @@ pub enum StabilityLevel {
161139 } ,
162140}
163141
142+ /// The available const-stability levels for const functions.
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+ ImplicitUnstable ,
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,51 @@ impl StabilityLevel {
187178 }
188179}
189180
181+ impl ConstStabilityLevel {
182+ pub fn is_const_unstable ( & self ) -> bool {
183+ matches ! ( self , ConstStabilityLevel :: Unstable { .. } | ConstStabilityLevel :: ImplicitUnstable )
184+ }
185+
186+ pub fn is_const_stable ( & self ) -> bool {
187+ matches ! ( self , ConstStabilityLevel :: Stable { .. } )
188+ }
189+
190+ pub fn is_implicit_unstable ( & self ) -> bool {
191+ matches ! ( self , ConstStabilityLevel :: ImplicitUnstable )
192+ }
193+ }
194+
195+ /// An instance of an `#[unstable]`, `#[rustc_const_unstable]`, or similar attribute
196+ #[ derive( Encodable , Decodable , PartialEq , Copy , Clone , Debug , Eq , Hash ) ]
197+ #[ derive( HashStable_Generic ) ]
198+ pub struct Unstability {
199+ pub feature : Symbol ,
200+ /// Reason for the current stability level.
201+ pub reason : UnstableReason ,
202+ /// Relevant `rust-lang/rust` issue.
203+ pub issue : Option < NonZero < u32 > > ,
204+ /// If part of a feature is stabilized and a new feature is added for the remaining parts,
205+ /// then the `implied_by` attribute is used to indicate which now-stable feature previously
206+ /// contained an item.
207+ ///
208+ /// ```pseudo-Rust
209+ /// #[unstable(feature = "foo", issue = "...")]
210+ /// fn foo() {}
211+ /// #[unstable(feature = "foo", issue = "...")]
212+ /// fn foobar() {}
213+ /// ```
214+ ///
215+ /// ...becomes...
216+ ///
217+ /// ```pseudo-Rust
218+ /// #[stable(feature = "foo", since = "1.XX.X")]
219+ /// fn foo() {}
220+ /// #[unstable(feature = "foobar", issue = "...", implied_by = "foo")]
221+ /// fn foobar() {}
222+ /// ```
223+ pub implied_by : Option < Symbol > ,
224+ }
225+
190226#[ derive( Encodable , Decodable , PartialEq , Copy , Clone , Debug , Eq , Hash ) ]
191227#[ derive( HashStable_Generic ) ]
192228pub enum UnstableReason {
@@ -233,8 +269,8 @@ pub fn find_stability(
233269 break ;
234270 }
235271
236- if let Some ( ( feature , level) ) = parse_unstability ( sess, attr) {
237- stab = Some ( ( Stability { level, feature } , attr. span ) ) ;
272+ if let Some ( level) = parse_unstability ( sess, attr) {
273+ stab = Some ( ( Stability { level } , attr. span ) ) ;
238274 }
239275 }
240276 sym:: stable => {
@@ -243,8 +279,8 @@ pub fn find_stability(
243279 . emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ;
244280 break ;
245281 }
246- if let Some ( ( feature , level) ) = parse_stability ( sess, attr) {
247- stab = Some ( ( Stability { level, feature } , attr. span ) ) ;
282+ if let Some ( level) = parse_stability ( sess, attr) {
283+ stab = Some ( ( Stability { level } , attr. span ) ) ;
248284 }
249285 }
250286 _ => { }
@@ -283,6 +319,10 @@ pub fn find_const_stability(
283319 let mut const_stab: Option < ( ConstStability , Span ) > = None ;
284320 let mut promotable = false ;
285321 let mut const_stable_indirect = None ;
322+ let const_stability_level = |level| match level {
323+ StabilityLevel :: Unstable { unstables, .. } => ConstStabilityLevel :: Unstable { unstables } ,
324+ StabilityLevel :: Stable { since, .. } => ConstStabilityLevel :: Stable { since } ,
325+ } ;
286326
287327 for attr in attrs {
288328 match attr. name_or_empty ( ) {
@@ -295,11 +335,10 @@ pub fn find_const_stability(
295335 break ;
296336 }
297337
298- if let Some ( ( feature , level) ) = parse_unstability ( sess, attr) {
338+ if let Some ( level) = parse_unstability ( sess, attr) {
299339 const_stab = Some ( (
300340 ConstStability {
301- level,
302- feature : Some ( feature) ,
341+ level : const_stability_level ( level) ,
303342 const_stable_indirect : false ,
304343 promotable : false ,
305344 } ,
@@ -313,11 +352,10 @@ pub fn find_const_stability(
313352 . emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ;
314353 break ;
315354 }
316- if let Some ( ( feature , level) ) = parse_stability ( sess, attr) {
355+ if let Some ( level) = parse_stability ( sess, attr) {
317356 const_stab = Some ( (
318357 ConstStability {
319- level,
320- feature : Some ( feature) ,
358+ level : const_stability_level ( level) ,
321359 const_stable_indirect : false ,
322360 promotable : false ,
323361 } ,
@@ -365,15 +403,9 @@ pub fn find_const_stability(
365403 // staged_api crate.
366404 if ( is_const_fn || const_stable_indirect. is_some ( ) ) && const_stab. is_none ( ) {
367405 let c = ConstStability {
368- feature : None ,
406+ level : ConstStabilityLevel :: ImplicitUnstable ,
369407 const_stable_indirect : const_stable_indirect. is_some ( ) ,
370408 promotable : false ,
371- level : StabilityLevel :: Unstable {
372- reason : UnstableReason :: Default ,
373- issue : None ,
374- is_soft : false ,
375- implied_by : None ,
376- } ,
377409 } ;
378410 const_stab = Some ( ( c, const_stable_indirect. unwrap_or ( DUMMY_SP ) ) ) ;
379411 }
@@ -397,8 +429,8 @@ pub fn find_body_stability(
397429 break ;
398430 }
399431
400- if let Some ( ( feature , level) ) = parse_unstability ( sess, attr) {
401- body_stab = Some ( ( DefaultBodyStability { level, feature } , attr. span ) ) ;
432+ if let Some ( level) = parse_unstability ( sess, attr) {
433+ body_stab = Some ( ( DefaultBodyStability { level } , attr. span ) ) ;
402434 }
403435 }
404436 }
@@ -424,7 +456,7 @@ fn insert_or_error(sess: &Session, meta: &MetaItem, item: &mut Option<Symbol>) -
424456
425457/// Read the content of a `stable`/`rustc_const_stable` attribute, and return the feature name and
426458/// its stability information.
427- fn parse_stability ( sess : & Session , attr : & Attribute ) -> Option < ( Symbol , StabilityLevel ) > {
459+ fn parse_stability ( sess : & Session , attr : & Attribute ) -> Option < StabilityLevel > {
428460 let meta = attr. meta ( ) ?;
429461 let MetaItem { kind : MetaItemKind :: List ( ref metas) , .. } = meta else { return None } ;
430462
@@ -478,17 +510,16 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
478510 } ;
479511
480512 match feature {
481- Ok ( feature) => {
482- let level = StabilityLevel :: Stable { since, allowed_through_unstable_modules : false } ;
483- Some ( ( feature, level) )
513+ Ok ( _feature) => {
514+ Some ( StabilityLevel :: Stable { since, allowed_through_unstable_modules : false } )
484515 }
485516 Err ( ErrorGuaranteed { .. } ) => None ,
486517 }
487518}
488519
489520/// Read the content of a `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable`
490521/// attribute, and return the feature name and its stability information.
491- fn parse_unstability ( sess : & Session , attr : & Attribute ) -> Option < ( Symbol , StabilityLevel ) > {
522+ fn parse_unstability ( sess : & Session , attr : & Attribute ) -> Option < StabilityLevel > {
492523 let meta = attr. meta ( ) ?;
493524 let MetaItem { kind : MetaItemKind :: List ( ref metas) , .. } = meta else { return None } ;
494525
@@ -568,12 +599,15 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
568599 match ( feature, issue) {
569600 ( Ok ( feature) , Ok ( _) ) => {
570601 let level = StabilityLevel :: Unstable {
571- reason : UnstableReason :: from_opt_reason ( reason) ,
572- issue : issue_num,
602+ unstables : Unstability {
603+ feature,
604+ reason : UnstableReason :: from_opt_reason ( reason) ,
605+ issue : issue_num,
606+ implied_by,
607+ } ,
573608 is_soft,
574- implied_by,
575609 } ;
576- Some ( ( feature , level) )
610+ Some ( level)
577611 }
578612 ( Err ( ErrorGuaranteed { .. } ) , _) | ( _, Err ( ErrorGuaranteed { .. } ) ) => None ,
579613 }
0 commit comments