@@ -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