@@ -70,7 +70,6 @@ pub enum OptimizeAttr {
70
70
#[ derive( HashStable_Generic ) ]
71
71
pub struct Stability {
72
72
pub level : StabilityLevel ,
73
- pub feature : Symbol ,
74
73
}
75
74
76
75
impl Stability {
@@ -88,13 +87,11 @@ impl Stability {
88
87
}
89
88
90
89
/// 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).
91
91
#[ derive( Encodable , Decodable , Copy , Clone , Debug , PartialEq , Eq , Hash ) ]
92
92
#[ derive( HashStable_Generic ) ]
93
93
pub 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 ,
98
95
/// This is true iff the `const_stable_indirect` attribute is present.
99
96
pub const_stable_indirect : bool ,
100
97
/// whether the function has a `#[rustc_promotable]` attribute
@@ -103,11 +100,15 @@ pub struct ConstStability {
103
100
104
101
impl ConstStability {
105
102
pub fn is_const_unstable ( & self ) -> bool {
106
- self . level . is_unstable ( )
103
+ self . level . is_const_unstable ( )
107
104
}
108
105
109
106
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 ( )
111
112
}
112
113
}
113
114
@@ -116,7 +117,6 @@ impl ConstStability {
116
117
#[ derive( HashStable_Generic ) ]
117
118
pub struct DefaultBodyStability {
118
119
pub level : StabilityLevel ,
119
- pub feature : Symbol ,
120
120
}
121
121
122
122
/// The available stability levels.
@@ -125,31 +125,9 @@ pub struct DefaultBodyStability {
125
125
pub enum StabilityLevel {
126
126
/// `#[unstable]`
127
127
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 ,
132
130
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 > ,
153
131
} ,
154
132
/// `#[stable]`
155
133
Stable {
@@ -161,6 +139,19 @@ pub enum StabilityLevel {
161
139
} ,
162
140
}
163
141
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
+
164
155
/// Rust release in which a feature is stabilized.
165
156
#[ derive( Encodable , Decodable , PartialEq , Copy , Clone , Debug , Eq , PartialOrd , Ord , Hash ) ]
166
157
#[ derive( HashStable_Generic ) ]
@@ -187,6 +178,51 @@ impl StabilityLevel {
187
178
}
188
179
}
189
180
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
+
190
226
#[ derive( Encodable , Decodable , PartialEq , Copy , Clone , Debug , Eq , Hash ) ]
191
227
#[ derive( HashStable_Generic ) ]
192
228
pub enum UnstableReason {
@@ -233,8 +269,8 @@ pub fn find_stability(
233
269
break ;
234
270
}
235
271
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 ) ) ;
238
274
}
239
275
}
240
276
sym:: stable => {
@@ -243,8 +279,8 @@ pub fn find_stability(
243
279
. emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ;
244
280
break ;
245
281
}
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 ) ) ;
248
284
}
249
285
}
250
286
_ => { }
@@ -283,6 +319,10 @@ pub fn find_const_stability(
283
319
let mut const_stab: Option < ( ConstStability , Span ) > = None ;
284
320
let mut promotable = false ;
285
321
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
+ } ;
286
326
287
327
for attr in attrs {
288
328
match attr. name_or_empty ( ) {
@@ -295,11 +335,10 @@ pub fn find_const_stability(
295
335
break ;
296
336
}
297
337
298
- if let Some ( ( feature , level) ) = parse_unstability ( sess, attr) {
338
+ if let Some ( level) = parse_unstability ( sess, attr) {
299
339
const_stab = Some ( (
300
340
ConstStability {
301
- level,
302
- feature : Some ( feature) ,
341
+ level : const_stability_level ( level) ,
303
342
const_stable_indirect : false ,
304
343
promotable : false ,
305
344
} ,
@@ -313,11 +352,10 @@ pub fn find_const_stability(
313
352
. emit_err ( session_diagnostics:: MultipleStabilityLevels { span : attr. span } ) ;
314
353
break ;
315
354
}
316
- if let Some ( ( feature , level) ) = parse_stability ( sess, attr) {
355
+ if let Some ( level) = parse_stability ( sess, attr) {
317
356
const_stab = Some ( (
318
357
ConstStability {
319
- level,
320
- feature : Some ( feature) ,
358
+ level : const_stability_level ( level) ,
321
359
const_stable_indirect : false ,
322
360
promotable : false ,
323
361
} ,
@@ -365,15 +403,9 @@ pub fn find_const_stability(
365
403
// staged_api crate.
366
404
if ( is_const_fn || const_stable_indirect. is_some ( ) ) && const_stab. is_none ( ) {
367
405
let c = ConstStability {
368
- feature : None ,
406
+ level : ConstStabilityLevel :: ImplicitUnstable ,
369
407
const_stable_indirect : const_stable_indirect. is_some ( ) ,
370
408
promotable : false ,
371
- level : StabilityLevel :: Unstable {
372
- reason : UnstableReason :: Default ,
373
- issue : None ,
374
- is_soft : false ,
375
- implied_by : None ,
376
- } ,
377
409
} ;
378
410
const_stab = Some ( ( c, const_stable_indirect. unwrap_or ( DUMMY_SP ) ) ) ;
379
411
}
@@ -397,8 +429,8 @@ pub fn find_body_stability(
397
429
break ;
398
430
}
399
431
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 ) ) ;
402
434
}
403
435
}
404
436
}
@@ -424,7 +456,7 @@ fn insert_or_error(sess: &Session, meta: &MetaItem, item: &mut Option<Symbol>) -
424
456
425
457
/// Read the content of a `stable`/`rustc_const_stable` attribute, and return the feature name and
426
458
/// its stability information.
427
- fn parse_stability ( sess : & Session , attr : & Attribute ) -> Option < ( Symbol , StabilityLevel ) > {
459
+ fn parse_stability ( sess : & Session , attr : & Attribute ) -> Option < StabilityLevel > {
428
460
let meta = attr. meta ( ) ?;
429
461
let MetaItem { kind : MetaItemKind :: List ( ref metas) , .. } = meta else { return None } ;
430
462
@@ -478,17 +510,16 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit
478
510
} ;
479
511
480
512
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 } )
484
515
}
485
516
Err ( ErrorGuaranteed { .. } ) => None ,
486
517
}
487
518
}
488
519
489
520
/// Read the content of a `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable`
490
521
/// 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 > {
492
523
let meta = attr. meta ( ) ?;
493
524
let MetaItem { kind : MetaItemKind :: List ( ref metas) , .. } = meta else { return None } ;
494
525
@@ -568,12 +599,15 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
568
599
match ( feature, issue) {
569
600
( Ok ( feature) , Ok ( _) ) => {
570
601
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
+ } ,
573
608
is_soft,
574
- implied_by,
575
609
} ;
576
- Some ( ( feature , level) )
610
+ Some ( level)
577
611
}
578
612
( Err ( ErrorGuaranteed { .. } ) , _) | ( _, Err ( ErrorGuaranteed { .. } ) ) => None ,
579
613
}
0 commit comments