1use std::num::NonZero;
2
3use rustc_macros::{Decodable, Encodable, HashStable_Generic, PrintAttribute};
4use rustc_span::{ErrorGuaranteed, Symbol, sym};
5
6use crate::RustcVersion;
7use crate::attrs::PrintAttribute;
8
9pub const VERSION_PLACEHOLDER: &str = concat!("CURRENT_RUSTC_VERSIO", "N");
14#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
25#[derive(HashStable_Generic, PrintAttribute)]
26pub struct Stability {
27 pub level: StabilityLevel,
28 pub feature: Symbol,
29}
30
31impl Stability {
32 pub fn is_unstable(&self) -> bool {
33 self.level.is_unstable()
34 }
35
36 pub fn is_stable(&self) -> bool {
37 self.level.is_stable()
38 }
39
40 pub fn stable_since(&self) -> Option<StableSince> {
41 self.level.stable_since()
42 }
43}
44
45#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
47#[derive(HashStable_Generic, PrintAttribute)]
48pub struct ConstStability {
49 pub level: StabilityLevel,
50 pub feature: Symbol,
51 pub promotable: bool,
53 pub const_stable_indirect: bool,
55}
56
57impl ConstStability {
58 pub fn from_partial(
59 PartialConstStability { level, feature, promotable }: PartialConstStability,
60 const_stable_indirect: bool,
61 ) -> Self {
62 Self { const_stable_indirect, level, feature, promotable }
63 }
64
65 pub fn unmarked(const_stable_indirect: bool, regular_stab: Stability) -> Self {
67 Self {
68 feature: regular_stab.feature,
69 promotable: false,
70 level: regular_stab.level,
71 const_stable_indirect,
72 }
73 }
74
75 pub fn is_const_unstable(&self) -> bool {
76 self.level.is_unstable()
77 }
78
79 pub fn is_const_stable(&self) -> bool {
80 self.level.is_stable()
81 }
82}
83
84#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
87#[derive(HashStable_Generic, PrintAttribute)]
88pub struct PartialConstStability {
89 pub level: StabilityLevel,
90 pub feature: Symbol,
91 pub promotable: bool,
93}
94
95impl PartialConstStability {
96 pub fn is_const_unstable(&self) -> bool {
97 self.level.is_unstable()
98 }
99
100 pub fn is_const_stable(&self) -> bool {
101 self.level.is_stable()
102 }
103}
104
105#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
107#[derive(HashStable_Generic, PrintAttribute)]
108pub enum StabilityLevel {
109 Unstable {
111 reason: UnstableReason,
113 issue: Option<NonZero<u32>>,
115 is_soft: bool,
116 implied_by: Option<Symbol>,
136 old_name: Option<Symbol>,
137 },
138 Stable {
140 since: StableSince,
142 allowed_through_unstable_modules: Option<Symbol>,
145 },
146}
147
148#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, PartialOrd, Ord, Hash)]
150#[derive(HashStable_Generic, PrintAttribute)]
151pub enum StableSince {
152 Version(RustcVersion),
154 Current,
156 Err(ErrorGuaranteed),
158}
159
160impl StabilityLevel {
161 pub fn is_unstable(&self) -> bool {
162 matches!(self, StabilityLevel::Unstable { .. })
163 }
164 pub fn is_stable(&self) -> bool {
165 matches!(self, StabilityLevel::Stable { .. })
166 }
167 pub fn stable_since(&self) -> Option<StableSince> {
168 match *self {
169 StabilityLevel::Stable { since, .. } => Some(since),
170 StabilityLevel::Unstable { .. } => None,
171 }
172 }
173}
174
175#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
176#[derive(HashStable_Generic, PrintAttribute)]
177pub enum UnstableReason {
178 None,
179 Default,
180 Some(Symbol),
181}
182
183#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
185#[derive(HashStable_Generic, PrintAttribute)]
186pub struct DefaultBodyStability {
187 pub level: StabilityLevel,
188 pub feature: Symbol,
189}
190
191impl UnstableReason {
192 pub fn from_opt_reason(reason: Option<Symbol>) -> Self {
193 match reason {
195 Some(r) => Self::Some(r),
196 None => Self::None,
197 }
198 }
199
200 pub fn to_opt_reason(&self) -> Option<Symbol> {
201 match self {
202 Self::None => None,
203 Self::Default => Some(sym::unstable_location_reason_default),
204 Self::Some(r) => Some(*r),
205 }
206 }
207}