@@ -137,8 +137,10 @@ pub struct DefaultBodyStability {
137
137
pub enum StabilityLevel {
138
138
/// `#[unstable]`
139
139
Unstable {
140
- /// The information unique to each `#[unstable]` attribute
140
+ /// The feature and optional github issue for each `#[unstable]` attribute
141
141
unstables : SmallVec < [ Unstability ; 1 ] > ,
142
+ /// Reason for the current stability level.
143
+ reason : UnstableReason ,
142
144
is_soft : bool ,
143
145
} ,
144
146
/// `#[stable]`
@@ -159,7 +161,12 @@ pub enum ConstStabilityLevel {
159
161
/// For functions declared const-stable
160
162
Stable { since : StableSince } ,
161
163
/// For functions declared const-unstable
162
- Unstable { unstables : SmallVec < [ Unstability ; 1 ] > } ,
164
+ Unstable {
165
+ /// The feature and optional github issue for each `#[rustc_const_unstable]` attribute
166
+ unstables : SmallVec < [ Unstability ; 1 ] > ,
167
+ /// Reason for the current stability level.
168
+ reason : UnstableReason ,
169
+ } ,
163
170
/// For functions with no explicit const-stability attribute that require checking recursive
164
171
/// const stability. This is either an unmarked const fn or a `const_stable_indirect` intrinsic.
165
172
Implicit ,
@@ -207,8 +214,8 @@ impl StabilityLevel {
207
214
208
215
fn to_const_stab_level ( self ) -> ConstStabilityLevel {
209
216
match self {
210
- StabilityLevel :: Unstable { unstables, .. } => {
211
- ConstStabilityLevel :: Unstable { unstables }
217
+ StabilityLevel :: Unstable { unstables, reason , .. } => {
218
+ ConstStabilityLevel :: Unstable { unstables, reason }
212
219
}
213
220
StabilityLevel :: Stable { since, .. } => ConstStabilityLevel :: Stable { since } ,
214
221
}
@@ -247,8 +254,6 @@ impl ConstStabilityLevel {
247
254
#[ derive( HashStable_Generic ) ]
248
255
pub struct Unstability {
249
256
pub feature : Symbol ,
250
- /// Reason for the current stability level.
251
- pub reason : UnstableReason ,
252
257
/// Relevant `rust-lang/rust` issue.
253
258
pub issue : Option < NonZero < u32 > > ,
254
259
/// If part of a feature is stabilized and a new feature is added for the remaining parts,
@@ -486,10 +491,18 @@ fn add_level(
486
491
( level @ None , new_level) => * level = Some ( new_level) ,
487
492
// if multiple unstable attributes have been found, merge them
488
493
(
489
- Some ( Unstable { unstables, is_soft } ) ,
490
- Unstable { unstables : new_unstable, is_soft : new_soft } ,
494
+ Some ( Unstable { unstables, reason , is_soft } ) ,
495
+ Unstable { unstables : new_unstable, reason : new_reason , is_soft : new_soft } ,
491
496
) => {
492
497
unstables. extend ( new_unstable) ;
498
+ match ( reason, new_reason) {
499
+ ( _, UnstableReason :: None ) => { }
500
+ ( reason @ UnstableReason :: None , _) => * reason = new_reason,
501
+ _ => {
502
+ sess. dcx ( )
503
+ . emit_err ( session_diagnostics:: MultipleUnstableReasons { span : attr. span } ) ;
504
+ }
505
+ }
493
506
// Make the unstability soft if any unstable attributes are marked 'soft'; if an
494
507
// unstable item is allowed in stable rust, another attribute shouldn't break that.
495
508
// FIXME(dianne): should there be a check that all unstables are soft if any are?
@@ -670,13 +683,12 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
670
683
671
684
match ( feature, issue) {
672
685
( Ok ( feature) , Ok ( _) ) => {
673
- let unstability = Unstability {
674
- feature,
686
+ let unstability = Unstability { feature, issue : issue_num, implied_by } ;
687
+ Some ( ( feature, StabilityLevel :: Unstable {
688
+ unstables : smallvec ! [ unstability] ,
675
689
reason : UnstableReason :: from_opt_reason ( reason) ,
676
- issue : issue_num,
677
- implied_by,
678
- } ;
679
- Some ( ( feature, StabilityLevel :: Unstable { unstables : smallvec ! [ unstability] , is_soft } ) )
690
+ is_soft,
691
+ } ) )
680
692
}
681
693
( Err ( ErrorGuaranteed { .. } ) , _) | ( _, Err ( ErrorGuaranteed { .. } ) ) => None ,
682
694
}
0 commit comments