@@ -137,8 +137,10 @@ pub struct DefaultBodyStability {
137137pub enum StabilityLevel {
138138 /// `#[unstable]`
139139 Unstable {
140- /// The information unique to each `#[unstable]` attribute
140+ /// The feature and optional github issue for each `#[unstable]` attribute
141141 unstables : SmallVec < [ Unstability ; 1 ] > ,
142+ /// Reason for the current stability level.
143+ reason : UnstableReason ,
142144 is_soft : bool ,
143145 } ,
144146 /// `#[stable]`
@@ -159,7 +161,12 @@ pub enum ConstStabilityLevel {
159161 /// For functions declared const-stable
160162 Stable { since : StableSince } ,
161163 /// 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+ } ,
163170 /// For functions with no explicit const-stability attribute that require checking recursive
164171 /// const stability. This is either an unmarked const fn or a `const_stable_indirect` intrinsic.
165172 Implicit ,
@@ -207,8 +214,8 @@ impl StabilityLevel {
207214
208215 fn to_const_stab_level ( self ) -> ConstStabilityLevel {
209216 match self {
210- StabilityLevel :: Unstable { unstables, .. } => {
211- ConstStabilityLevel :: Unstable { unstables }
217+ StabilityLevel :: Unstable { unstables, reason , .. } => {
218+ ConstStabilityLevel :: Unstable { unstables, reason }
212219 }
213220 StabilityLevel :: Stable { since, .. } => ConstStabilityLevel :: Stable { since } ,
214221 }
@@ -247,8 +254,6 @@ impl ConstStabilityLevel {
247254#[ derive( HashStable_Generic ) ]
248255pub struct Unstability {
249256 pub feature : Symbol ,
250- /// Reason for the current stability level.
251- pub reason : UnstableReason ,
252257 /// Relevant `rust-lang/rust` issue.
253258 pub issue : Option < NonZero < u32 > > ,
254259 /// If part of a feature is stabilized and a new feature is added for the remaining parts,
@@ -486,10 +491,18 @@ fn add_level(
486491 ( level @ None , new_level) => * level = Some ( new_level) ,
487492 // if multiple unstable attributes have been found, merge them
488493 (
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 } ,
491496 ) => {
492497 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+ }
493506 // Make the unstability soft if any unstable attributes are marked 'soft'; if an
494507 // unstable item is allowed in stable rust, another attribute shouldn't break that.
495508 // 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
670683
671684 match ( feature, issue) {
672685 ( 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] ,
675689 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+ } ) )
680692 }
681693 ( Err ( ErrorGuaranteed { .. } ) , _) | ( _, Err ( ErrorGuaranteed { .. } ) ) => None ,
682694 }
0 commit comments