@@ -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,
@@ -485,10 +490,18 @@ fn add_level(
485490 ( level @ None , new_level) => * level = Some ( new_level) ,
486491 // if multiple unstable attributes have been found, merge them
487492 (
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 } ,
490495 ) => {
491496 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+ }
492505 // Make the unstability soft if any unstable attributes are marked 'soft'; if an
493506 // unstable item is allowed in stable rust, another attribute shouldn't break that.
494507 // 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
669682
670683 match ( feature, issue) {
671684 ( 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] ,
674688 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+ } ) )
679691 }
680692 ( Err ( ErrorGuaranteed { .. } ) , _) | ( _, Err ( ErrorGuaranteed { .. } ) ) => None ,
681693 }
0 commit comments