@@ -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,
@@ -485,10 +490,18 @@ fn add_level(
485
490
( level @ None , new_level) => * level = Some ( new_level) ,
486
491
// if multiple unstable attributes have been found, merge them
487
492
(
488
- Some ( Unstable { unstables, is_soft } ) ,
489
- Unstable { unstables : new_unstable, is_soft : new_soft } ,
493
+ Some ( Unstable { unstables, reason , is_soft } ) ,
494
+ Unstable { unstables : new_unstable, reason : new_reason , is_soft : new_soft } ,
490
495
) => {
491
496
unstables. extend ( new_unstable) ;
497
+ match ( reason, new_reason) {
498
+ ( _, UnstableReason :: None ) => { }
499
+ ( reason @ UnstableReason :: None , _) => * reason = new_reason,
500
+ _ => {
501
+ sess. dcx ( )
502
+ . emit_err ( session_diagnostics:: MultipleUnstableReasons { span : attr. span } ) ;
503
+ }
504
+ }
492
505
// Make the unstability soft if any unstable attributes are marked 'soft'; if an
493
506
// unstable item is allowed in stable rust, another attribute shouldn't break that.
494
507
// FIXME(dianne): should there be a check that all unstables are soft if any are?
@@ -669,13 +682,12 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil
669
682
670
683
match ( feature, issue) {
671
684
( Ok ( feature) , Ok ( _) ) => {
672
- let unstability = Unstability {
673
- feature,
685
+ let unstability = Unstability { feature, issue : issue_num, implied_by } ;
686
+ Some ( ( feature, StabilityLevel :: Unstable {
687
+ unstables : smallvec ! [ unstability] ,
674
688
reason : UnstableReason :: from_opt_reason ( reason) ,
675
- issue : issue_num,
676
- implied_by,
677
- } ;
678
- Some ( ( feature, StabilityLevel :: Unstable { unstables : smallvec ! [ unstability] , is_soft } ) )
689
+ is_soft,
690
+ } ) )
679
691
}
680
692
( Err ( ErrorGuaranteed { .. } ) , _) | ( _, Err ( ErrorGuaranteed { .. } ) ) => None ,
681
693
}
0 commit comments